hub_kernel-api
Serves a hub_kernel hub's exposed methods as a JSON API. The host lists the hubs it serves, and every call goes through the host's own sign-in, then the permission check and account scope that hub_kernel-interface holds. It depends on hub_kernel-interface alone, not on hub_kernel.
Usage
Add the gem, then in an initializer name the controller the API inherits from, the two methods on it that give the person and the account a call is made for, and the hubs it serves:
HubKernel::Api.base_controller = "Api::HubBaseController"
HubKernel::Api.person_method = :current_person
HubKernel::Api.account_method = :current_account
Rails.application.config.to_prepare do
HubKernel::Api.hubs = [ Supplies ]
HubKernel::Api.check!
endWhen HubKernel::Api.person_method or HubKernel::Api.account_method is not set, the JSON
API uses HubKernel::Interface.person_method or HubKernel::Interface.account_method, so a
host that also serves hub_kernel-mcp can name the caller once in hub_kernel-interface. The
JSON API's own setting is used when it is set.
HubKernel::Api.check! raises HubKernel::Api::UnservableHubError when a served entry
exposes no methods, when two served hubs answer at the same address, or when a served
hub's exposed list has a problem, naming each. Inside to_prepare it runs again after
every code reload.
HubKernel::Api.hubs reads and writes hub_kernel-interface's one served list,
HubKernel::Interface.hubs, so every interface gem in the host, such as hub_kernel-mcp,
serves the same hubs at the same names. The list is set once, through either gem.
The base controller's own sign-in runs before every call. The permission check and account
scope must also be set, HubKernel::Authz.check and HubKernel::Context.scope, as
hub_kernel-interface's readme describes. Mount the engine:
mount HubKernel::Api::Engine => "/api/v1/hubs"Each exposed method answers at /<hub>/<method>, where <hub> is the hub's module name
underscored. To answer at a name of the host's choosing, list the hub as a one-pair hash:
HubKernel::Api.hubs = [ Supplies, { "money" => Billing::Ledger } ]A hub listed this way answers only at the name given, and the permission check is still
asked about it by its own name, such as ledger:record_spend. A read answers GET and a write answers POST, and the answer is the method's
return value under answer.
A GET at a served hub's own address, /<hub>, lists the methods the caller may call on
the account the host names, each with its name, the values it takes and its verb:
[{ "name": "price_of", "takes": ["item"], "verb": "GET" }]A hub that is not served is answered as not found, and a caller the host's sign-in refuses is shown nothing.
| Case | Status | Body |
|---|---|---|
| The method answers | 200 | {"answer": ...} |
| The hub is not served, the method is not exposed, the verb is wrong, or the host's permission check refuses | 404 | {"error": "Not found"} |
| The hub refuses, or a required value is missing | 422 | {"error": "<reason>"} |
| A permitted call sends a value the method is not listed with | 422 | {"error": "<method> does not take <values>"} |
| A record the call names does not exist | 404 | {"error": "No <record> has the id <id>"} |
Installation
gem "hub_kernel-api"License
The gem is available as open source under the terms of the MIT License.