Skip to content
fwereade edited this page Dec 3, 2015 · 7 revisions

Facades

A facade is a collection of API methods organised for a specific purpose. It's a pretty fundamental concept: our versioning is at facade granularity, and a facade's most fundamental responsibility is to validate incoming API calls and ensure that they're sensible before taking action.

What exactly is a Facade?

Any type can be a facade; but if it doesn't have exported methods with suitable signatures, it won't be very interesting. Specifically, any exported method which (1) takes either 0 or 1 args; and (2) returns either (result) or (result, error): will be exposed over the websocket rpc connection.

What creates a Facade?

When an api request is received, the apiserver chooses a facade constructor, based on the request's rootName and version; then constructs the facade and calls the method corresponding to the request's methodName. (Many details elided.) Note that the facade is created for the use of, and persists only for the lifetime of, a single request.

Why would I want to write a Facade?

If any of the following conditions applies:

  • you're writing a new worker inside an agent
  • you're changing some existing worker, and it needs new capabilities
  • you're exposing some new domain of functionality to an external user
  • you're changing or extending some such exposed functionality

...you need to be writing and registering a new Facade. If it's a new worker or a new domain, it should definitely be in a new subpackage of apiserver; if it's a change to an existing one it still needs a new facade -- to be registered under a new version -- but it should go in the same package as its predecessors.

How do I write a Facade?

  • don't import state

  • really, please, don't import state

  • define or locate interfaces that expose the capabilities your facade requires

    • these might well be or want to be defined under core, if they're semi-mature
    • if it's a locally defined interface that's fine too
    • if it's defined somewhere else in the codebase, be suspicious: probably, either you're depending on unnecessary concretions, or that interface is defined in the wrong place.
  • write a simple constructor for your facade, most likely using the config-struct pattern, and making sure to include an apiserver/common.Authorizer:

    package 
    
    type Config
    

How do I test a Facade?

How do I register my Facade?

note this dependency on mutable global state is bad. If someone were to fix it I would be most grateful.

  • in your facade package
Clone this wiki locally