microsoft / microsoft/vscode-documentdb

Evolve the Service Discovery plugin API so plugins need no core integration points

Open
#739 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
31
Forks
22
Avg merge
2d 20h
Merged PRs (30d)
21

Description

Summary

The Service Discovery plugin API is experimental and intentionally so. As we add new discovery plugins, we keep discovering new requirements that the current API does not yet cover, and we adapt the API to meet them. This is expected at this stage. This issue tracks the next iteration: closing the remaining gaps that today force a plugin to reach into generic extension code instead of being fully self-contained behind the API.

The newly added Kubernetes service discovery plugin (#621) is the motivating example. It works well, but to deliver its full experience it required a few direct integrations into generic command code rather than expressing everything through the discovery plugin API.

Goal

Explore and design how a plugin like Kubernetes discovery could be built using only the discovery plugin API, with no imports from the plugin into core command/tree code. The long-term intent is to graduate this into an official, exposed integration API so third parties can ship discovery plugins out-of-tree.

Known coupling points to remove

These two generic commands currently import directly from src/plugins/service-kubernetes/. Both are marked with FIXME (discovery plugin API coupling) comments in code that reference this issue.

1. copyConnectionString — provider-contributed copy actions

src/commands/copyConnectionString/copyConnectionString.ts

  • Today: the command imports getKubernetesPortForwardMetadata / KubernetesPortForwardMetadata to render a Kubernetes-specific grouped quick pick (the reproducing kubectl port-forward command, a "Learn more" entry, and a port-forward warning message).
  • Proposed design: add an optional getConnectionStringCopyContribution?(node, credentials) hook to the DiscoveryProvider API that returns extra quick-pick items, a custom completion message, and a "read-only" flag. The command iterates registered providers instead of importing any plugin. All Kubernetes knowledge (metadata parsing + kubectl string building) moves back into the plugin.
  • The read-only credential half is already decoupled via structural typing (getCredentialsForCopy duck type), which is a good pattern to build on.
2. newConnection/ExecuteStep — provider-defined connection identity

src/commands/newConnection/ExecuteStep.ts

  • Today: the command imports getKubernetesPortForwardMetadata / getKubernetesPortForwardIdentity to special-case duplicate-connection detection (two port-forward tunnels can share localhost:<port> yet point at different services, so host + username is not a reliable key).
  • Proposed design: have the plugin write a generic connectionIdentity string into the already source-agnostic context.connectionProperties bag when it builds a connection. The dedup logic compares connectionIdentity when both sides have one and falls back to host + username otherwise. The command stays plugin-agnostic; the plugin decides what makes two of its connections "the same".

Note: the generic connectionProperties?: Record<string, unknown> bag added to NewConnectionWizardContext in #621 is already a good, source-agnostic extension point and is the natural carrier for the design above.

Out of scope / already done well

These extension points already point the right direction and should be treated as the model for the rest of the API:

  • DiscoveryProvider.configureCredentials?(), deactivate?(), and configureCredentialsOnActivation? hooks.
  • The denylist-based provider visibility model (hiddenDiscoveryProviderIds) so newly registered providers are visible by default.
  • The getCredentialsForCopy read-only credentials duck type.

A note on the experimental status

We knew from the start that this API is experimental, and we are deliberately adapting it to new requirements as each new plugin is added. The coupling described above is a snapshot of that evolution, not a defect to be ashamed of. At some point the API will be exposed as an official integration API.

Contributions welcome

  • Contributions toward this API design and the decoupling above are very welcome.
  • Proposals for new discovery plugins are also welcome — new plugins are the best way to surface the requirements the official API must support. Please open a discussion or issue to start the conversation.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with src/commands/copyConnectionString/copyConnectionString.ts and src/commands/newConnection/ExecuteStep.ts, following the FIXME comments and their direct Kubernetes imports. Read the DiscoveryProvider API and NewConnectionWizardContext, then compare the existing extension points and connectionProperties bag. Done means both commands are plugin-agnostic while Kubernetes supplies its copy contribution and connection identity through the API.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.