haveapi 0.3.2 → 0.4.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/CHANGELOG +12 -0
- data/Gemfile +10 -10
- data/README.md +19 -12
- data/Rakefile +23 -0
- data/doc/hooks.erb +35 -0
- data/doc/index.md +1 -0
- data/doc/json-schema.erb +369 -0
- data/doc/protocol.md +178 -38
- data/doc/protocol.plantuml +220 -0
- data/haveapi.gemspec +6 -10
- data/lib/haveapi/action.rb +35 -6
- data/lib/haveapi/api.rb +22 -5
- data/lib/haveapi/common.rb +7 -0
- data/lib/haveapi/exceptions.rb +7 -0
- data/lib/haveapi/hooks.rb +19 -8
- data/lib/haveapi/model_adapters/active_record.rb +58 -19
- data/lib/haveapi/output_formatter.rb +8 -5
- data/lib/haveapi/output_formatters/json.rb +6 -1
- data/lib/haveapi/params/param.rb +33 -39
- data/lib/haveapi/params/resource.rb +20 -0
- data/lib/haveapi/params.rb +26 -4
- data/lib/haveapi/public/doc/protocol.png +0 -0
- data/lib/haveapi/resource.rb +2 -7
- data/lib/haveapi/server.rb +87 -26
- data/lib/haveapi/tasks/hooks.rb +3 -0
- data/lib/haveapi/tasks/yard.rb +12 -0
- data/lib/haveapi/validator.rb +134 -0
- data/lib/haveapi/validator_chain.rb +99 -0
- data/lib/haveapi/validators/acceptance.rb +38 -0
- data/lib/haveapi/validators/confirmation.rb +46 -0
- data/lib/haveapi/validators/custom.rb +21 -0
- data/lib/haveapi/validators/exclusion.rb +38 -0
- data/lib/haveapi/validators/format.rb +42 -0
- data/lib/haveapi/validators/inclusion.rb +42 -0
- data/lib/haveapi/validators/length.rb +71 -0
- data/lib/haveapi/validators/numericality.rb +104 -0
- data/lib/haveapi/validators/presence.rb +40 -0
- data/lib/haveapi/version.rb +2 -1
- data/lib/haveapi/views/doc_sidebars/json-schema.erb +7 -0
- data/lib/haveapi/views/main_layout.erb +11 -0
- data/lib/haveapi/views/version_page.erb +26 -3
- data/lib/haveapi.rb +7 -4
- metadata +45 -66
data/doc/protocol.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
HaveAPI defines the format for the self-description and URLs where the self-description
|
3
3
|
can be found.
|
4
4
|
|
5
|
-
|
5
|
+
# Self-description
|
6
6
|
The API is self-describing. It documents itself. Clients use the self-description
|
7
7
|
to work with the API. The Self-description contains access URLs, HTTP methods,
|
8
8
|
input and output parameters and their validators.
|
@@ -20,7 +20,19 @@ Thanks to this ability, API changes immediately reflects in all clients without
|
|
20
20
|
changing a single line of code. A client can also be used on all APIs with compatible
|
21
21
|
self-describing format, without any changes at all.
|
22
22
|
|
23
|
-
|
23
|
+
# Protocol versioning
|
24
|
+
Protocol version defines the form and contents of
|
25
|
+
|
26
|
+
- the envelope,
|
27
|
+
- API description,
|
28
|
+
- data transfers.
|
29
|
+
|
30
|
+
Protocol version is in the form `<major>.<minor>`. `major` is incremented
|
31
|
+
whenever a change is made to the protocol that breaks backward compatibility.
|
32
|
+
When backward compatibility is kept and only some new features are added to the
|
33
|
+
protocol, `major` stays and `minor` is incremented.
|
34
|
+
|
35
|
+
# Envelope
|
24
36
|
In addition to output format specified below, every API response
|
25
37
|
is wrapped in an envelope.
|
26
38
|
The envelope reports if action succeeded or failed, provides return value or error
|
@@ -36,12 +48,23 @@ messages.
|
|
36
48
|
}
|
37
49
|
}
|
38
50
|
|
39
|
-
|
51
|
+
Responses for `OPTIONS` requests also send a protocol version in the envelope:
|
52
|
+
|
53
|
+
"version": <version>
|
54
|
+
|
55
|
+
# Description format
|
40
56
|
In this document, the self-description is encoded in JSON. However, it can
|
41
57
|
be encoded in any of the supported output formats.
|
42
58
|
|
43
|
-
|
44
|
-
|
59
|
+
## API version
|
60
|
+
|
61
|
+
<a href="/doc/protocol.png">
|
62
|
+
<img src="/doc/protocol.png"
|
63
|
+
alt="Diagram representing the structure of an API version"
|
64
|
+
width="600">
|
65
|
+
</a>
|
66
|
+
|
67
|
+
API version is described as:
|
45
68
|
|
46
69
|
{
|
47
70
|
"authentication": {
|
@@ -50,15 +73,15 @@ Version is described as:
|
|
50
73
|
"resources": {
|
51
74
|
... resources ...
|
52
75
|
},
|
53
|
-
|
54
|
-
|
55
|
-
|
76
|
+
"meta": {
|
77
|
+
"namespace": "_meta"
|
78
|
+
},
|
56
79
|
"help": "/<version>/"
|
57
80
|
}
|
58
81
|
|
59
82
|
See appropriate section for detailed description of each section.
|
60
83
|
|
61
|
-
|
84
|
+
## Authentication
|
62
85
|
HaveAPI defines an interface for implementing custom authentication methods.
|
63
86
|
HTTP basic and token authentication is built-in.
|
64
87
|
|
@@ -66,12 +89,12 @@ Authentication methods can be set per API version. They are a part of
|
|
66
89
|
the self-description, but must be understood by the client.
|
67
90
|
The client can choose whichever available authentication method he prefers.
|
68
91
|
|
69
|
-
|
92
|
+
### HTTP basic authentication
|
70
93
|
HTTP basic authentication needs no other configuration, only informs about its presence.
|
71
94
|
|
72
95
|
"basic": {}
|
73
96
|
|
74
|
-
|
97
|
+
### Token authentication
|
75
98
|
Token authentication contains a resource ``token``, that is used
|
76
99
|
to acquire and revoke token.
|
77
100
|
|
@@ -114,7 +137,7 @@ Token can be revoked by calling the ``revoke`` action.
|
|
114
137
|
|
115
138
|
The format for ``resources`` section is the same as for any other resource.
|
116
139
|
|
117
|
-
|
140
|
+
## Resources
|
118
141
|
Each resource is described as:
|
119
142
|
|
120
143
|
"<resource_name>": {
|
@@ -127,7 +150,7 @@ Each resource is described as:
|
|
127
150
|
}
|
128
151
|
}
|
129
152
|
|
130
|
-
|
153
|
+
## Actions
|
131
154
|
Every action is described as:
|
132
155
|
|
133
156
|
"<action_name>": {
|
@@ -157,7 +180,7 @@ Every action is described as:
|
|
157
180
|
"help": "URL to get this very description of the action"
|
158
181
|
}
|
159
182
|
|
160
|
-
|
183
|
+
### Layouts
|
161
184
|
Layout type is specified for input/output parameters. Thanks to the layout type,
|
162
185
|
clients know how to send the request and how to interpret the response.
|
163
186
|
|
@@ -172,7 +195,7 @@ In client libraries, the ``object`` layout output usually results in returning
|
|
172
195
|
an object that represents the instance of the resource. The parameters are defined
|
173
196
|
as object properties and the like.
|
174
197
|
|
175
|
-
|
198
|
+
### Namespace
|
176
199
|
All input/output parameters are put in a namespace, which is usually
|
177
200
|
the name of the resource.
|
178
201
|
|
@@ -184,10 +207,10 @@ For example:
|
|
184
207
|
}
|
185
208
|
}
|
186
209
|
|
187
|
-
|
210
|
+
## Parameters
|
188
211
|
There are two parameter types.
|
189
212
|
|
190
|
-
|
213
|
+
### Data types
|
191
214
|
The type can be one of:
|
192
215
|
|
193
216
|
- String
|
@@ -202,16 +225,133 @@ The type can be one of:
|
|
202
225
|
"label": "Label for this parameter",
|
203
226
|
"description": "Describe it's meaning",
|
204
227
|
"type": "<one of the data types>",
|
205
|
-
"choices": a list or a hash of accepted values
|
206
228
|
"validators": ... validators ...,
|
207
229
|
"default": "default value that is used if the parameter is omitted"
|
208
230
|
}
|
209
231
|
|
210
|
-
|
211
|
-
|
232
|
+
|
233
|
+
#### Validators
|
234
|
+
Every parameter has its own validators. Any of the following validators
|
235
|
+
may be present. Input value must pass through all validators in order
|
236
|
+
to be considered valid.
|
237
|
+
|
238
|
+
##### Acceptance
|
239
|
+
Used when a parameter must have one specific value.
|
240
|
+
|
241
|
+
"accept": {
|
242
|
+
"value": <value to accept>,
|
243
|
+
"message": "has to be <value>"
|
244
|
+
}
|
245
|
+
|
246
|
+
##### Presence
|
247
|
+
The parameter must be present. If `empty` is `false`, leading and trailing
|
248
|
+
whitespace is stripped before the check.
|
249
|
+
|
250
|
+
"present": {
|
251
|
+
empty: true/false,
|
252
|
+
message: "must be present"
|
253
|
+
}
|
254
|
+
|
255
|
+
##### Confirmation
|
256
|
+
Used to confirm that two parameters have either the same value or not have the
|
257
|
+
same value. The former can be used e.g. to verify that passwords are same
|
258
|
+
and the latter to give two different e-mail addresses.
|
259
|
+
|
260
|
+
"confirm": {
|
261
|
+
"equal": true/false,
|
262
|
+
"parameter": <parameter_name>,
|
263
|
+
"message": "must (or must not) be the same as <parameter_name>"
|
264
|
+
}
|
265
|
+
|
266
|
+
##### Inclusion
|
267
|
+
The parameter can contain only one of given options.
|
268
|
+
|
269
|
+
"include": {
|
270
|
+
"values": ["list", "of", "allowed", "values"],
|
271
|
+
"message": "%{value} cannot be used"
|
272
|
+
}
|
273
|
+
|
274
|
+
If the `values` are a list, than it is a list of accepted values.
|
275
|
+
If the `values` are a hash, the keys of that hash are accepted values,
|
212
276
|
values in that hash are to be shown in UI.
|
213
277
|
|
214
|
-
|
278
|
+
"include": {
|
279
|
+
"values": {
|
280
|
+
"one": "Fancy one",
|
281
|
+
"two": "Fancy two"
|
282
|
+
},
|
283
|
+
"message": "%{value} cannot be used"
|
284
|
+
}
|
285
|
+
|
286
|
+
##### Exclusion
|
287
|
+
The parameter can be set to anything except values listed here.
|
288
|
+
|
289
|
+
"exclude": {
|
290
|
+
"values": ["list", "of", "excluded", "values"],
|
291
|
+
"message": "%{value} cannot be used"
|
292
|
+
}
|
293
|
+
|
294
|
+
##### Specific format
|
295
|
+
If `match` is true, the parameter must pass given regular expression.
|
296
|
+
Otherwise it must not pass the regular expression.
|
297
|
+
|
298
|
+
"format": {
|
299
|
+
"rx": "regular expression",
|
300
|
+
"match": true/false,
|
301
|
+
"description": "human-readable description of the regular expression",
|
302
|
+
"message": "%{value} is not in a valid format"
|
303
|
+
}
|
304
|
+
|
305
|
+
##### Length
|
306
|
+
Useful only for `String` and `Text` parameters. Checks the length of given string.
|
307
|
+
It may check either
|
308
|
+
|
309
|
+
- minimum
|
310
|
+
- maximum
|
311
|
+
- minimum and maximum
|
312
|
+
- constant length
|
313
|
+
|
314
|
+
The length validator must therefore contain one or more checks, but cannot
|
315
|
+
contain both min/max and equality.
|
316
|
+
|
317
|
+
Length range:
|
318
|
+
|
319
|
+
"length": {
|
320
|
+
"min": 0,
|
321
|
+
"max": 99,
|
322
|
+
"message": "length has to be in range <0,99>"
|
323
|
+
}
|
324
|
+
|
325
|
+
Constant length:
|
326
|
+
|
327
|
+
"length": {
|
328
|
+
"equals": 10,
|
329
|
+
"message": "length has to be 10"
|
330
|
+
}
|
331
|
+
|
332
|
+
##### Numericality
|
333
|
+
Numericality implies that the parameter must be a number, i.e. `Integer`, `Float`
|
334
|
+
or `String` containing only digits. It can check that the number is in a specified
|
335
|
+
range and can provide a step. The validator can contain one or more of these conditions.
|
336
|
+
|
337
|
+
"number": {
|
338
|
+
"min": 0,
|
339
|
+
"max": 99,
|
340
|
+
"step": 3,
|
341
|
+
"mod": 3,
|
342
|
+
"even": true/false,
|
343
|
+
"odd": true/false
|
344
|
+
}
|
345
|
+
|
346
|
+
##### Custom validation
|
347
|
+
Custom validation cannot be documented by the API. The developer may or may not
|
348
|
+
provide information that some non-documented validation takes place. The documentation
|
349
|
+
contains only the description of the validations that may be shown to the user,
|
350
|
+
but is not evaluated client-side, only server-side.
|
351
|
+
|
352
|
+
"custom": "description of custom validation"
|
353
|
+
|
354
|
+
### Resource association
|
215
355
|
This is used for associations between resources, e.g. car has a wheel.
|
216
356
|
|
217
357
|
"<parameter_name>": {
|
@@ -243,7 +383,7 @@ can show the human-friendly label instead of just an ID.
|
|
243
383
|
"<value of value_label from description>": "<label>"
|
244
384
|
}
|
245
385
|
|
246
|
-
|
386
|
+
## Examples
|
247
387
|
Examples are described in a generic way, so that every client can
|
248
388
|
render them according to its syntax.
|
249
389
|
|
@@ -258,24 +398,24 @@ render them according to its syntax.
|
|
258
398
|
"comment": "Description of the example"
|
259
399
|
}
|
260
400
|
|
261
|
-
|
401
|
+
## Metadata
|
262
402
|
Metadata can be global and per-object. Global metadata are sent once for each
|
263
403
|
response, where as per-object are sent with each object that is a part of the
|
264
404
|
response.
|
265
405
|
|
266
406
|
{
|
267
407
|
"global": {
|
268
|
-
|
269
|
-
|
270
|
-
|
408
|
+
"input": ... parameters or null ...,
|
409
|
+
"output: ... parameters or null ...
|
410
|
+
} or null,
|
271
411
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
412
|
+
"object": {
|
413
|
+
"input": ... parameters or null ...,
|
414
|
+
"output: ... parameters or null ...
|
415
|
+
} or null,
|
276
416
|
}
|
277
417
|
|
278
|
-
|
418
|
+
## List API versions
|
279
419
|
Send request ``OPTIONS /?describe=versions``. The description format:
|
280
420
|
|
281
421
|
{
|
@@ -283,11 +423,11 @@ Send request ``OPTIONS /?describe=versions``. The description format:
|
|
283
423
|
"default": <which version is default>
|
284
424
|
}
|
285
425
|
|
286
|
-
|
426
|
+
## Describe default version
|
287
427
|
Send request ``OPTIONS /?describe=default`` the get the description
|
288
428
|
of the default version.
|
289
429
|
|
290
|
-
|
430
|
+
## Describe the whole API
|
291
431
|
It is possible to get self-description of all versions at once.
|
292
432
|
|
293
433
|
Send request ``OPTIONS /``. The description format:
|
@@ -301,20 +441,20 @@ Send request ``OPTIONS /``. The description format:
|
|
301
441
|
}
|
302
442
|
}
|
303
443
|
|
304
|
-
|
444
|
+
# Authorization
|
305
445
|
Actions may require different levels of authorization. HaveAPI provides means for
|
306
446
|
implementing authorization, but it is not self-described.
|
307
447
|
|
308
448
|
If the user is authenticated when requesting self-description, only allowed
|
309
449
|
resources/actions/parameters will be returned.
|
310
450
|
|
311
|
-
|
451
|
+
# Input/output formats
|
312
452
|
For now, the only supported input format is JSON.
|
313
453
|
|
314
454
|
Output format can be chosen by a client. However, no other format than JSON is built-in.
|
315
455
|
The output format can be chosen with HTTP header ``Accept``.
|
316
456
|
|
317
|
-
|
457
|
+
# Request
|
318
458
|
Action URL and HTTP method the client learns from the self-description.
|
319
459
|
|
320
460
|
Example request:
|
@@ -332,7 +472,7 @@ Example request:
|
|
332
472
|
}
|
333
473
|
}
|
334
474
|
|
335
|
-
|
475
|
+
# Response
|
336
476
|
Clients know how to interpret the response thanks to the layout type they learn
|
337
477
|
from the self-description.
|
338
478
|
|
@@ -349,7 +489,7 @@ Example response to the request above:
|
|
349
489
|
"name": "Very Name",
|
350
490
|
"role": "admin"
|
351
491
|
}
|
352
|
-
|
492
|
+
},
|
353
493
|
"message": null,
|
354
494
|
"errors: null
|
355
495
|
}
|
@@ -0,0 +1,220 @@
|
|
1
|
+
@startuml
|
2
|
+
|
3
|
+
class Version {
|
4
|
+
help : String
|
5
|
+
}
|
6
|
+
|
7
|
+
class Meta {
|
8
|
+
namespace : String
|
9
|
+
}
|
10
|
+
|
11
|
+
abstract class Authentication {
|
12
|
+
|
13
|
+
}
|
14
|
+
|
15
|
+
class Basic {
|
16
|
+
|
17
|
+
}
|
18
|
+
|
19
|
+
class Token {
|
20
|
+
http_header : String
|
21
|
+
query_parameter : String
|
22
|
+
}
|
23
|
+
|
24
|
+
class Resource {
|
25
|
+
name : String
|
26
|
+
description : String
|
27
|
+
}
|
28
|
+
|
29
|
+
class Action {
|
30
|
+
name : String
|
31
|
+
auth : Bool
|
32
|
+
description : String
|
33
|
+
aliases : list
|
34
|
+
url : String
|
35
|
+
method : String
|
36
|
+
help : String
|
37
|
+
}
|
38
|
+
|
39
|
+
class Example {
|
40
|
+
title : String
|
41
|
+
request : hash
|
42
|
+
response : hash
|
43
|
+
comment : String
|
44
|
+
}
|
45
|
+
|
46
|
+
class Parameters {
|
47
|
+
layout : String
|
48
|
+
namespace : String
|
49
|
+
}
|
50
|
+
|
51
|
+
abstract class Parameter {
|
52
|
+
required : Bool
|
53
|
+
label : String
|
54
|
+
description : String
|
55
|
+
type : String
|
56
|
+
}
|
57
|
+
|
58
|
+
class InputParameter {
|
59
|
+
default : any
|
60
|
+
}
|
61
|
+
|
62
|
+
class OutputParameter {
|
63
|
+
|
64
|
+
}
|
65
|
+
|
66
|
+
abstract class ResourceParameter {
|
67
|
+
value_id : String
|
68
|
+
value_label : String
|
69
|
+
}
|
70
|
+
|
71
|
+
class TypedInputParameter {
|
72
|
+
|
73
|
+
}
|
74
|
+
|
75
|
+
class ResourceInputParameter {
|
76
|
+
}
|
77
|
+
|
78
|
+
class TypedOutputParameter {
|
79
|
+
|
80
|
+
}
|
81
|
+
|
82
|
+
class ResourceOutputParameter {
|
83
|
+
}
|
84
|
+
|
85
|
+
class ResourceLink {
|
86
|
+
url : String
|
87
|
+
method : String
|
88
|
+
help : String
|
89
|
+
}
|
90
|
+
|
91
|
+
|
92
|
+
class ActionMeta {
|
93
|
+
}
|
94
|
+
|
95
|
+
abstract class Validator {
|
96
|
+
message : String
|
97
|
+
}
|
98
|
+
|
99
|
+
class AcceptanceValidator {
|
100
|
+
value : any
|
101
|
+
}
|
102
|
+
|
103
|
+
class ConfirmationValidator {
|
104
|
+
equal : Bool
|
105
|
+
}
|
106
|
+
|
107
|
+
class CustomValidator {
|
108
|
+
description : String
|
109
|
+
}
|
110
|
+
|
111
|
+
class ExclusionValidator {
|
112
|
+
values : list
|
113
|
+
}
|
114
|
+
|
115
|
+
class FormatValidator {
|
116
|
+
rx : RegExp
|
117
|
+
match : Bool
|
118
|
+
description : String
|
119
|
+
}
|
120
|
+
|
121
|
+
abstract class InclusionValidator {
|
122
|
+
|
123
|
+
}
|
124
|
+
|
125
|
+
class ArrayInclusionValidator {
|
126
|
+
values : list
|
127
|
+
}
|
128
|
+
|
129
|
+
class HashInclusionValidator {
|
130
|
+
values : hash
|
131
|
+
}
|
132
|
+
|
133
|
+
abstract class LengthValidator {
|
134
|
+
|
135
|
+
}
|
136
|
+
|
137
|
+
class EqualLengthValidator {
|
138
|
+
equals : Integer
|
139
|
+
}
|
140
|
+
|
141
|
+
class RangeLengthValidator {
|
142
|
+
min : Integer
|
143
|
+
max : Integer
|
144
|
+
}
|
145
|
+
|
146
|
+
class NumericalityValidator {
|
147
|
+
min : Number
|
148
|
+
max : Number
|
149
|
+
step : Number
|
150
|
+
mod : Integer
|
151
|
+
odd : Bool
|
152
|
+
even : Bool
|
153
|
+
}
|
154
|
+
|
155
|
+
class PresenceValidator {
|
156
|
+
empty : Bool
|
157
|
+
}
|
158
|
+
|
159
|
+
Version -- Meta
|
160
|
+
Version *-- Authentication
|
161
|
+
|
162
|
+
Authentication <|-- Basic
|
163
|
+
Authentication <|-- Token
|
164
|
+
|
165
|
+
Token *-- Resource
|
166
|
+
|
167
|
+
Version *-- Resource
|
168
|
+
|
169
|
+
Resource *-- Resource
|
170
|
+
Resource *-- Action
|
171
|
+
|
172
|
+
Action *-- Example
|
173
|
+
Action -- Parameters : input
|
174
|
+
Action -- Parameters : output
|
175
|
+
Action -- ActionMeta : object
|
176
|
+
Action -- ActionMeta : global
|
177
|
+
|
178
|
+
ActionMeta -- Parameters : input
|
179
|
+
ActionMeta -- Parameters : output
|
180
|
+
|
181
|
+
Parameters *-- Parameter
|
182
|
+
|
183
|
+
Parameter <|-- InputParameter
|
184
|
+
Parameter <|-- OutputParameter
|
185
|
+
Parameter <|-- ResourceParameter
|
186
|
+
|
187
|
+
ResourceParameter <|-- ResourceInputParameter
|
188
|
+
ResourceParameter <|-- ResourceOutputParameter
|
189
|
+
ResourceParameter -- Resource : associated with
|
190
|
+
|
191
|
+
InputParameter <|-- TypedInputParameter
|
192
|
+
InputParameter <|-- ResourceInputParameter
|
193
|
+
|
194
|
+
TypedInputParameter *-- Validator
|
195
|
+
|
196
|
+
Validator <|-- AcceptanceValidator
|
197
|
+
Validator <|-- ConfirmationValidator
|
198
|
+
ConfirmationValidator -- InputParameter : confirms
|
199
|
+
Validator <|-- CustomValidator
|
200
|
+
Validator <|-- ExclusionValidator
|
201
|
+
Validator <|-- FormatValidator
|
202
|
+
Validator <|-- InclusionValidator
|
203
|
+
InclusionValidator <|-- ArrayInclusionValidator
|
204
|
+
InclusionValidator <|-- HashInclusionValidator
|
205
|
+
Validator <|-- LengthValidator
|
206
|
+
LengthValidator <|-- EqualLengthValidator
|
207
|
+
LengthValidator <|-- RangeLengthValidator
|
208
|
+
Validator <|-- NumericalityValidator
|
209
|
+
Validator <|-- PresenceValidator
|
210
|
+
|
211
|
+
OutputParameter <|-- TypedOutputParameter
|
212
|
+
OutputParameter <|-- ResourceOutputParameter
|
213
|
+
|
214
|
+
ResourceInputParameter -- ResourceLink : value
|
215
|
+
ResourceInputParameter -- ResourceLink : choices
|
216
|
+
|
217
|
+
ResourceOutputParameter -- ResourceLink : value
|
218
|
+
ResourceOutputParameter -- ResourceLink : choices
|
219
|
+
|
220
|
+
@enduml
|
data/haveapi.gemspec
CHANGED
@@ -5,7 +5,7 @@ require 'haveapi/version'
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = 'haveapi'
|
7
7
|
s.version = HaveAPI::VERSION
|
8
|
-
s.date = '
|
8
|
+
s.date = '2016-01-20'
|
9
9
|
s.summary =
|
10
10
|
s.description = 'Framework for creating self-describing APIs'
|
11
11
|
s.authors = 'Jakub Skokan'
|
@@ -15,16 +15,12 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.required_ruby_version = '~> 2.0'
|
17
17
|
|
18
|
-
s.add_runtime_dependency 'activerecord', '~> 4.1.6'
|
19
18
|
s.add_runtime_dependency 'require_all'
|
20
19
|
s.add_runtime_dependency 'json'
|
21
|
-
s.add_runtime_dependency 'sinatra'
|
22
|
-
s.add_runtime_dependency '
|
23
|
-
s.add_runtime_dependency '
|
20
|
+
s.add_runtime_dependency 'sinatra', '~> 1.4.6'
|
21
|
+
s.add_runtime_dependency 'tilt', '~> 1.4.1'
|
22
|
+
s.add_runtime_dependency 'redcarpet', '~> 3.3.4'
|
24
23
|
s.add_runtime_dependency 'rake'
|
25
|
-
s.add_runtime_dependency 'github-markdown', '~> 0.6.
|
26
|
-
|
27
|
-
s.add_development_dependency 'rspec'
|
28
|
-
s.add_development_dependency 'railties'
|
29
|
-
s.add_development_dependency 'rack-test'
|
24
|
+
s.add_runtime_dependency 'github-markdown', '~> 0.6.9'
|
25
|
+
s.add_runtime_dependency 'nesty', '~> 1.0.2'
|
30
26
|
end
|
data/lib/haveapi/action.rb
CHANGED
@@ -11,7 +11,16 @@ module HaveAPI
|
|
11
11
|
|
12
12
|
include Hookable
|
13
13
|
|
14
|
-
has_hook :exec_exception
|
14
|
+
has_hook :exec_exception,
|
15
|
+
desc: 'Called when unhandled exceptions occurs during Action.exec',
|
16
|
+
args: {
|
17
|
+
action: 'HaveAPI::Action instance',
|
18
|
+
exception: 'exception instance',
|
19
|
+
},
|
20
|
+
ret: {
|
21
|
+
status: 'true or false, indicating whether error should be reported',
|
22
|
+
message: 'error message sent to the user',
|
23
|
+
}
|
15
24
|
|
16
25
|
attr_reader :message, :errors, :version
|
17
26
|
attr_accessor :flags
|
@@ -65,10 +74,14 @@ module HaveAPI
|
|
65
74
|
def initialize
|
66
75
|
return if @initialized
|
67
76
|
|
68
|
-
input
|
69
|
-
|
77
|
+
check_build("#{self}.input") do
|
78
|
+
input.exec
|
79
|
+
model_adapter(input.layout).load_validators(model, input) if model
|
80
|
+
end
|
70
81
|
|
71
|
-
output
|
82
|
+
check_build("#{self}.output") do
|
83
|
+
output.exec
|
84
|
+
end
|
72
85
|
|
73
86
|
model_adapter(input.layout).used_by(:input, self)
|
74
87
|
model_adapter(output.layout).used_by(:output, self)
|
@@ -76,14 +89,30 @@ module HaveAPI
|
|
76
89
|
if @meta
|
77
90
|
@meta.each_value do |m|
|
78
91
|
next unless m
|
79
|
-
|
80
|
-
|
92
|
+
|
93
|
+
check_build("#{self}.meta.input") do
|
94
|
+
m.input && m.input.exec
|
95
|
+
end
|
96
|
+
|
97
|
+
check_build("#{self}.meta.output") do
|
98
|
+
m.output && m.output.exec
|
99
|
+
end
|
81
100
|
end
|
82
101
|
end
|
83
102
|
|
84
103
|
@initialized = true
|
85
104
|
end
|
86
105
|
|
106
|
+
def validate_build
|
107
|
+
check_build("#{self}.input") do
|
108
|
+
input.validate_build
|
109
|
+
end
|
110
|
+
|
111
|
+
check_build("#{self}.output") do
|
112
|
+
output.validate_build
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
87
116
|
def model_adapter(layout)
|
88
117
|
ModelAdapter.for(layout, resource.model)
|
89
118
|
end
|