0.0
The project is in a healthy, maintained state
hub_kernel-api gives any hub built on hub_kernel a JSON API: the host lists the hubs it serves, and every call goes through the host's sign-in, permission check and account scope.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

 Project Readme

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!
end

When 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.