-
Notifications
You must be signed in to change notification settings - Fork 0
API best practices
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.
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.
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.
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.
-
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.
- these might well be or want to be defined under
-
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
note this dependency on mutable global state is bad. If someone were to fix it I would be most grateful.
- in your facade package
Testing
Releases
Documentation
Development
- READ BEFORE CODING
- Blocking bugs process
- Bug fixes and patching
- Contributing
- Code Review Checklists
- Creating New Repos
-
MongoDB and Consistency
- [mgo/txn Example] (https://github.com/juju/juju/wiki/mgo-txn-example)
- Scripts
- Update Launchpad Dependency
- Writing workers
- Reviewboard Tips
Debugging and QA
- Debugging Juju
- [Faster LXD] (https://github.com/juju/juju/wiki/Faster-LXD)