• Packages
  • Themes
  • Documentation
  • Blog
  • Discuss
Subscribe

New Services API

March 25, 2015 jlord jlord Tweet

Many packages don't just work in isolation, they depend on other packages. For instance, the vim-mode package depends on the status-bar package because it uses it to display the current editing mode.

statusbar

Previously a package like vim-mode would be forced to wait for all packages to load and then query the DOM for the status-bar in order to interact with it. Not only was this cumbersome, but it also created the possibility for breakage if the API of the status-bar ever changed.

Node's package manager, npm, solves a similar problem for static dependencies by giving each library its own copy of its dependencies based on a semantic version range. But in this case, we can't give every package its own copy of the status bar, since there's only one status bar in the atom workspace.

Providing and Consuming Services

Atom's solution is the new Services API, which allows packages to provide semantically versioned APIs for other packages to consume. With services, the status-bar package can provide multiple versions of its API simultaneously, providing a smooth upgrade path for dependent packages when the status-bar package evolves its API.

Services will also provide flex-points in the package ecosystem by enabling any package to provide the same service. For example, if someone wanted to implement a status-bar-plus package with a new and improved status bar, they could still provide the original status-bar's services in order to be compatible with packages such as vim-mode. This ensures that authors will enjoy a level playing field when competing against incumbent packages by preventing calcification of the dependency graph.

Packages define what they are providing and consuming in their package.json. The status-bar package's package.json contains its provided services API with two versioned methods:

"providedServices": {
  "status-bar": {
    "description": "A container for indicators at the bottom of the workspace",
    "versions": {
      "1.0.0": "provideStatusBar",
      "0.58.0": "legacyProvideStatusBar"
    }
  }
}

This gives other packages access to the status-bar method provideSatusBar when they consume the 'status-bar' service. The vim-mode package does so by declaring in its package.json:

"consumedServices": {
  "status-bar": {
    "versions": {
      "^1.0.0": "consumeStatusBar"
    }
  }
}

Now when vim-mode calls consumeStatusBar it is returned the result of the provideStatusBar method from status-bar which it can then use to insert the user's current state.

consumeStatusBar: (statusBar) ->
    @statusBarManager.initialize(statusBar)
    @statusBarManager.attach()
    @disposables.add new Disposable =>
      @statusBarManager.detach()

For more details on the Services API see Interacting with Other Packages via Services in the documentation.

Have feedback on this post? Let @AtomEditor know on Twitter.

Need help or found a bug? Contact us.

  • Terms of Use
  • Releases
  • FAQ
  • Contact
with by