hub_kernel-api 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +236 -2
- data/app/controllers/hub_kernel/api/hub_calls_controller.rb +7 -1
- data/app/controllers/hub_kernel/api/hub_controller.rb +46 -2
- data/app/controllers/hub_kernel/api/hubs_controller.rb +1 -5
- data/app/controllers/hub_kernel/api/versions_controller.rb +15 -0
- data/config/routes.rb +1 -0
- data/lib/hub_kernel/api/description.rb +17 -0
- data/lib/hub_kernel/api/description_check.rb +54 -0
- data/lib/hub_kernel/api/description_files.rb +13 -0
- data/lib/hub_kernel/api/earlier_answers.rb +11 -0
- data/lib/hub_kernel/api/major_version.rb +13 -0
- data/lib/hub_kernel/api/test_helper.rb +24 -0
- data/lib/hub_kernel/api/version.rb +1 -1
- data/lib/hub_kernel/api.rb +72 -1
- data/lib/tasks/hub_kernel_api.rake +14 -0
- data/the_local/agents/hub_kernel-api-develop.md +343 -41
- data/the_local/agents/hub_kernel-api-info.md +102 -13
- data/the_local/agents/hub_kernel-api-install.md +118 -17
- data/the_local/interface.yml +26 -0
- metadata +11 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hub_kernel-api-install
|
|
3
|
-
description: Use to hook hub_kernel-api into a project — adding the gem, naming the base controller and its person and account methods, listing the served hubs, running the startup check, and mounting the engine.
|
|
3
|
+
description: Use to hook hub_kernel-api into a project — adding the gem, naming the base controller and its person and account methods, listing the served hubs, listing the majors served and marking the ones deprecated or retired, running the startup check, and mounting the engine.
|
|
4
4
|
tools: Bash, Read, Edit
|
|
5
5
|
scope: hub JSON API — serving a hub_kernel hub's exposed methods as a JSON API in a host Rails app, each call behind the host's own sign-in and hub_kernel-interface's permission check and account scope
|
|
6
6
|
---
|
|
@@ -20,14 +20,31 @@ in when a Rails app needs its hubs callable over HTTP.
|
|
|
20
20
|
- `HubKernel::Api.base_controller=` — the name, as a String, of the host controller the
|
|
21
21
|
API's controllers inherit from; defaults to `"ActionController::API"`.
|
|
22
22
|
- `HubKernel::Api.person_method=` — the name, as a Symbol, of the method on the base
|
|
23
|
-
controller that returns the person a call is made for;
|
|
23
|
+
controller that returns the person a call is made for; when unset, the API uses
|
|
24
|
+
`HubKernel::Interface.person_method`.
|
|
24
25
|
- `HubKernel::Api.account_method=` — the name, as a Symbol, of the method on the base
|
|
25
|
-
controller that returns the account a call is made for;
|
|
26
|
+
controller that returns the account a call is made for; when unset, the API uses
|
|
27
|
+
`HubKernel::Interface.account_method`.
|
|
26
28
|
- `HubKernel::Api.hubs=` — the Array of hubs the API serves, each a hub module or a
|
|
27
29
|
one-pair Hash of address to hub module; defaults to empty.
|
|
28
|
-
- `HubKernel::Api.
|
|
30
|
+
- `HubKernel::Api.versions=` — the Array of majors the API serves, each a
|
|
31
|
+
`HubKernel::Api::MajorVersion`; defaults to empty, which turns versioning off.
|
|
32
|
+
- `HubKernel::Api::MajorVersion` — one listed major, built as
|
|
33
|
+
`HubKernel::Api::MajorVersion.new(version: "1.4.0")`; its major is the first part of
|
|
34
|
+
the version. `deprecated: true` marks a major the host still serves but plans to stop
|
|
35
|
+
serving, `deprecated_on:` gives a deprecated major the `Date` it was deprecated, and
|
|
36
|
+
`sunset:` gives it the `Date` it stops being served. `retired: true` marks a major the
|
|
37
|
+
host keeps listed but no longer serves.
|
|
38
|
+
- `HubKernel::Api.check!` — checks the served hubs and the listed majors, and raises if
|
|
39
|
+
any hub cannot be served or the majors hold a mistake.
|
|
29
40
|
- `HubKernel::Api::UnservableHubError` — the error `check!` raises, its message naming
|
|
30
41
|
every problem on its own line.
|
|
42
|
+
- `HubKernel::Api::UnservedMajorError` — the error the API raises when a call or a listing
|
|
43
|
+
names a major the host does not list, whether or not the hub it names is served; the API
|
|
44
|
+
answers that call with status 406 and the error's message, and the host does not rescue it.
|
|
45
|
+
- `HubKernel::Api::RetiredMajorError` — the error the API raises when a call or a listing
|
|
46
|
+
names a retired major, whether or not the hub it names is served; the API answers that
|
|
47
|
+
call with status 410 and the error's message, and the host does not rescue it.
|
|
31
48
|
- `mount HubKernel::Api::Engine` — the routes line that puts the API at a path in the host.
|
|
32
49
|
|
|
33
50
|
## How to use it
|
|
@@ -55,17 +72,58 @@ in when a Rails app needs its hubs callable over HTTP.
|
|
|
55
72
|
Do not leave the default `ActionController::API`: it has no sign-in and no person or
|
|
56
73
|
account method, so every call would fail.
|
|
57
74
|
|
|
58
|
-
4.
|
|
75
|
+
4. Check whether the host already sets `HubKernel::Interface.person_method` and
|
|
76
|
+
`HubKernel::Interface.account_method`, for example for hub_kernel-mcp. If it does and
|
|
77
|
+
the base controller defines those same methods, ask the developer whether to rely on
|
|
78
|
+
them or to set `HubKernel::Api.person_method` and `HubKernel::Api.account_method`. If
|
|
79
|
+
it does not, set both on `HubKernel::Api`.
|
|
80
|
+
|
|
81
|
+
5. Ask the developer which hubs to serve and at what address each answers. A hub module
|
|
59
82
|
answers at its module name underscored, so `Supplies` answers at `supplies`. To use a
|
|
60
83
|
different address, the hub is listed as a one-pair Hash, `{ "money" => Billing::Ledger }`.
|
|
61
|
-
Every listed hub must expose methods, and no two may share an address.
|
|
62
|
-
|
|
63
|
-
|
|
84
|
+
Every listed hub must expose methods, and no two may share an address. The served list
|
|
85
|
+
is the one hub_kernel-interface holds, so another interface gem in the host, such as
|
|
86
|
+
hub_kernel-mcp, serves the same list; set it once, through either gem.
|
|
87
|
+
|
|
88
|
+
6. Ask the developer whether the API serves major versions, and if it does, the full
|
|
89
|
+
version of each major, in major.minor.patch form. Put these facts to them:
|
|
90
|
+
- With no majors listed, every call gets the method's own answer, a call that names a
|
|
91
|
+
major is answered as though it named none, and the API reports no version.
|
|
92
|
+
- With majors listed, a call or listing that names no major is answered at the oldest
|
|
93
|
+
major listed that is not retired, so listing majors on a host with existing clients
|
|
94
|
+
changes the answers and the answer shapes those clients receive unless that major is
|
|
95
|
+
the one they were built against.
|
|
96
|
+
- A major marked `retired: true` stays listed, and every call or listing that names it
|
|
97
|
+
is answered with status 410.
|
|
98
|
+
- A major marked `deprecated: true` is still answered, and every answer at it gives the
|
|
99
|
+
caller its `deprecated_on:` date and its `sunset:` date.
|
|
100
|
+
- `deprecated_on:` and `sunset:` on a major not marked `deprecated: true` are never sent
|
|
101
|
+
to a caller.
|
|
102
|
+
- `HubKernel::Api.check!` refuses to boot the host when the list holds any of these:
|
|
103
|
+
a version not a string in major.minor.patch form, a major listed twice, a deprecated major
|
|
104
|
+
missing `deprecated_on:` or `sunset:`, a `deprecated_on:` or `sunset:` that is not a
|
|
105
|
+
`Date`, or every listed major retired.
|
|
106
|
+
- It also refuses when a served hub declares an earlier answer for a major the host
|
|
107
|
+
does not list, or for the newest major listed. Ask the developer which majors their
|
|
108
|
+
hubs already declare earlier answers for, and list each of those majors.
|
|
109
|
+
|
|
110
|
+
Ask which majors, if any, are deprecated, and for each one the date it was deprecated
|
|
111
|
+
and the date it stops being served; both dates are required. Ask which majors, if any,
|
|
112
|
+
are retired, and keep at least one not retired. Do not mark a major deprecated or
|
|
113
|
+
retired without the developer's word: deprecating one tells every client built against
|
|
114
|
+
it to move, and retiring one stops every such client getting answers.
|
|
115
|
+
|
|
116
|
+
7. Create `config/initializers/hub_kernel_api.rb` with the answers from steps 3 to 6:
|
|
64
117
|
|
|
65
118
|
```ruby
|
|
66
119
|
HubKernel::Api.base_controller = "Api::HubBaseController"
|
|
67
120
|
HubKernel::Api.person_method = :current_person
|
|
68
121
|
HubKernel::Api.account_method = :current_account
|
|
122
|
+
HubKernel::Api.versions = [
|
|
123
|
+
HubKernel::Api::MajorVersion.new(version: "1.4.0", retired: true),
|
|
124
|
+
HubKernel::Api::MajorVersion.new(version: "2.0.1", deprecated: true, deprecated_on: Date.new(2026, 9, 30), sunset: Date.new(2027, 3, 31)),
|
|
125
|
+
HubKernel::Api::MajorVersion.new(version: "3.1.0")
|
|
126
|
+
]
|
|
69
127
|
|
|
70
128
|
Rails.application.config.to_prepare do
|
|
71
129
|
HubKernel::Api.hubs = [ Supplies, { "money" => Billing::Ledger } ]
|
|
@@ -73,37 +131,80 @@ in when a Rails app needs its hubs callable over HTTP.
|
|
|
73
131
|
end
|
|
74
132
|
```
|
|
75
133
|
|
|
76
|
-
- `base_controller`, `person_method` and `
|
|
77
|
-
outside `to_prepare`. The base controller name is read once, when the
|
|
78
|
-
controllers load, so it must be set before then.
|
|
134
|
+
- `base_controller`, `person_method`, `account_method` and `versions` go at the top of
|
|
135
|
+
the file, outside `to_prepare`. The base controller name is read once, when the
|
|
136
|
+
API's controllers load, so it must be set before then.
|
|
137
|
+
- Leave out the `versions` line when the developer chose to serve no majors.
|
|
138
|
+
- Add `deprecated: true` only to the majors the developer named as deprecated.
|
|
139
|
+
- Add `deprecated_on:` and `sunset:` to each of them, as `Date` values, with the dates
|
|
140
|
+
the developer gave.
|
|
141
|
+
- Add `retired: true` only to the majors the developer named as retired.
|
|
79
142
|
- `hubs` and `check!` go inside `to_prepare`, so the hub constants resolve after each
|
|
80
143
|
code reload and the check runs again after each one.
|
|
81
144
|
|
|
82
|
-
|
|
145
|
+
8. Ask the developer the path to mount the API at, then add the mount to
|
|
83
146
|
`config/routes.rb`:
|
|
84
147
|
|
|
85
148
|
```ruby
|
|
86
149
|
mount HubKernel::Api::Engine => "/api/v1/hubs"
|
|
87
150
|
```
|
|
88
151
|
|
|
89
|
-
|
|
152
|
+
9. Boot the app, for example with `bin/rails runner "puts :ok"`. A
|
|
90
153
|
`HubKernel::Api::UnservableHubError` at boot names each problem:
|
|
91
154
|
- `<Hub> exposes no methods to serve` — the entry is not a hub with exposed methods;
|
|
92
155
|
remove it, or expose methods on it.
|
|
93
156
|
- `<Hub> and <Hub> both answer at <address>` — give one of them its own address with
|
|
94
157
|
a one-pair Hash.
|
|
158
|
+
- `The listed version <version> is not in major.minor.patch form` — write that
|
|
159
|
+
entry's `version:` as a string such as `"2.1.0"`.
|
|
160
|
+
- `Major <n> is listed more than once` — keep one entry for that major.
|
|
161
|
+
- `Major <n> is deprecated with no deprecated_on: date it was deprecated` or
|
|
162
|
+
`... with no sunset: date it stops being served` — ask the developer for the missing
|
|
163
|
+
date and add it.
|
|
164
|
+
- `Major <n> gives deprecated_on: as <value>, which is not a Date` or the same for
|
|
165
|
+
`sunset:` — write the date as `Date.new(year, month, day)`.
|
|
166
|
+
- `Every listed major is retired, ...` — ask the developer which major to stop
|
|
167
|
+
retiring, or which new major to list.
|
|
168
|
+
- `<Hub> declares an earlier answer to <method> for major <n>, which the host does not
|
|
169
|
+
list` — ask the developer whether to list that major or have the hub's earlier answer
|
|
170
|
+
removed.
|
|
171
|
+
- `<Hub> declares an earlier answer to <method> for major <n>, the newest major, ...` —
|
|
172
|
+
ask the developer whether to list a newer major or have that earlier answer removed.
|
|
95
173
|
- Any other line is a problem the hub reports with its own list of exposed methods;
|
|
96
174
|
fix it in the hub.
|
|
97
175
|
|
|
176
|
+
Every problem is named in the one error, so fix them all before booting again.
|
|
177
|
+
|
|
98
178
|
## Conventions
|
|
99
179
|
|
|
100
180
|
- Run `bin/rails routes` after mounting and confirm the engine appears at the chosen path.
|
|
101
181
|
- To serve another hub later, add it to the `hubs` list inside `to_prepare` and boot
|
|
102
182
|
again so `check!` runs.
|
|
183
|
+
- To serve a new major, add a `HubKernel::Api::MajorVersion` to `versions`.
|
|
184
|
+
- To warn clients that a major will stop being served, add `deprecated: true`,
|
|
185
|
+
`deprecated_on:` with the date it was deprecated, and `sunset:` with the date it stops
|
|
186
|
+
being served. Retire it on that date; nothing retires it when the date passes.
|
|
187
|
+
- To stop serving a major, ask the developer whether to retire it or remove it. Adding
|
|
188
|
+
`retired: true` keeps it listed, and every call that names it answers with status 410
|
|
189
|
+
and a message naming the newest major. Removing it while others stay listed makes every
|
|
190
|
+
call that names it answer with status 406, the same as a major never listed.
|
|
191
|
+
- Retiring or removing the oldest major that is not retired moves every call that names
|
|
192
|
+
no major to the next oldest one.
|
|
193
|
+
- Removing every major turns versioning off, and calls that name a major get the
|
|
194
|
+
method's own answer.
|
|
195
|
+
- Removing a major that a served hub declares an earlier answer for, or removing the
|
|
196
|
+
newest major while a hub declares an earlier answer for the one below it, stops the host
|
|
197
|
+
booting; boot again after every change to `versions` so `check!` runs.
|
|
198
|
+
- With no majors listed, `check!` checks none of the version rules.
|
|
103
199
|
- An edit to the initializer takes effect only after the server restarts.
|
|
104
|
-
- Keep `HubKernel::Api.check!` in the initializer; without it a hub that cannot be served
|
|
105
|
-
is found only when a client calls
|
|
200
|
+
- Keep `HubKernel::Api.check!` in the initializer; without it a hub that cannot be served,
|
|
201
|
+
or a mistake in `versions`, is found only when a client calls the API.
|
|
106
202
|
- Setting the permission check and account scope is out of scope here; it belongs to
|
|
107
203
|
hub_kernel-interface.
|
|
108
|
-
-
|
|
109
|
-
|
|
204
|
+
- Declaring a method's answers at earlier majors is out of scope here; it belongs to
|
|
205
|
+
hub_kernel-interface.
|
|
206
|
+
- When a listed major's minor must be raised in `versions`, because that major's answers
|
|
207
|
+
gained something, is out of scope here; it belongs to the develop local.
|
|
208
|
+
- Calling the API, naming a major on a call, its responses, its error statuses and
|
|
209
|
+
writing each major's description file are out of scope here; they belong to the
|
|
210
|
+
develop local.
|
data/the_local/interface.yml
CHANGED
|
@@ -6,20 +6,46 @@ install:
|
|
|
6
6
|
- HubKernel::Api.person_method=
|
|
7
7
|
- HubKernel::Api.account_method=
|
|
8
8
|
- HubKernel::Api.hubs=
|
|
9
|
+
- HubKernel::Api.versions=
|
|
10
|
+
- HubKernel::Api::MajorVersion
|
|
9
11
|
- HubKernel::Api.check!
|
|
10
12
|
- HubKernel::Api::UnservableHubError
|
|
13
|
+
- HubKernel::Api::UnservedMajorError
|
|
14
|
+
- HubKernel::Api::RetiredMajorError
|
|
11
15
|
- mount HubKernel::Api::Engine
|
|
12
16
|
|
|
13
17
|
develop:
|
|
18
|
+
- GET /
|
|
14
19
|
- GET /<hub>
|
|
15
20
|
- GET /<hub>/<method>
|
|
16
21
|
- POST /<hub>/<method>
|
|
22
|
+
- Accept-Version
|
|
23
|
+
- Api-Version
|
|
24
|
+
- Api-Newest-Version
|
|
25
|
+
- Deprecation
|
|
26
|
+
- Sunset
|
|
27
|
+
- Vary
|
|
28
|
+
- answer_shape
|
|
29
|
+
- bin/rails hub_kernel_api:describe
|
|
30
|
+
- bin/rails hub_kernel_api:check_descriptions
|
|
31
|
+
- HubKernel::Api::BreakingChangeError
|
|
32
|
+
- api_descriptions/v<major>.json
|
|
33
|
+
- HubKernel::Api::TestHelper
|
|
34
|
+
- assert_answer_shape
|
|
17
35
|
|
|
18
36
|
sources:
|
|
19
37
|
- lib/hub_kernel/api.rb
|
|
20
38
|
- lib/hub_kernel/api/engine.rb
|
|
39
|
+
- lib/hub_kernel/api/major_version.rb
|
|
40
|
+
- lib/hub_kernel/api/description.rb
|
|
41
|
+
- lib/hub_kernel/api/description_files.rb
|
|
42
|
+
- lib/hub_kernel/api/description_check.rb
|
|
43
|
+
- lib/hub_kernel/api/earlier_answers.rb
|
|
44
|
+
- lib/hub_kernel/api/test_helper.rb
|
|
45
|
+
- lib/tasks/hub_kernel_api.rake
|
|
21
46
|
- config/routes.rb
|
|
22
47
|
- app/controllers/hub_kernel/api/hub_controller.rb
|
|
23
48
|
- app/controllers/hub_kernel/api/hubs_controller.rb
|
|
24
49
|
- app/controllers/hub_kernel/api/hub_calls_controller.rb
|
|
50
|
+
- app/controllers/hub_kernel/api/versions_controller.rb
|
|
25
51
|
- README.md
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hub_kernel-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- tylercschneider
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '0.
|
|
32
|
+
version: '0.10'
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '0.
|
|
39
|
+
version: '0.10'
|
|
40
40
|
description: 'hub_kernel-api gives any hub built on hub_kernel a JSON API: the host
|
|
41
41
|
lists the hubs it serves, and every call goes through the host''s sign-in, permission
|
|
42
42
|
check and account scope.'
|
|
@@ -52,11 +52,19 @@ files:
|
|
|
52
52
|
- app/controllers/hub_kernel/api/hub_calls_controller.rb
|
|
53
53
|
- app/controllers/hub_kernel/api/hub_controller.rb
|
|
54
54
|
- app/controllers/hub_kernel/api/hubs_controller.rb
|
|
55
|
+
- app/controllers/hub_kernel/api/versions_controller.rb
|
|
55
56
|
- config/routes.rb
|
|
56
57
|
- lib/hub_kernel-api.rb
|
|
57
58
|
- lib/hub_kernel/api.rb
|
|
59
|
+
- lib/hub_kernel/api/description.rb
|
|
60
|
+
- lib/hub_kernel/api/description_check.rb
|
|
61
|
+
- lib/hub_kernel/api/description_files.rb
|
|
62
|
+
- lib/hub_kernel/api/earlier_answers.rb
|
|
58
63
|
- lib/hub_kernel/api/engine.rb
|
|
64
|
+
- lib/hub_kernel/api/major_version.rb
|
|
65
|
+
- lib/hub_kernel/api/test_helper.rb
|
|
59
66
|
- lib/hub_kernel/api/version.rb
|
|
67
|
+
- lib/tasks/hub_kernel_api.rake
|
|
60
68
|
- the_local/agents/hub_kernel-api-develop.md
|
|
61
69
|
- the_local/agents/hub_kernel-api-info.md
|
|
62
70
|
- the_local/agents/hub_kernel-api-install.md
|