-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSON Parameters and Headers #3
Changes from all commits
7728fa9
0a4d846
8741e08
74e1b57
25f199e
b07167e
054b8c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
--- | ||
RFC: XXXX | ||
Author: Z | ||
Status: Draft | ||
Created: 2015-09-23 | ||
Last Modified: 2015-09-28 | ||
--- | ||
|
||
# API Blueprint RFC XXXX: MSON Parameters and Headers | ||
|
||
## Table of Contents | ||
|
||
- [Abstract](#abstract) | ||
- [Motivation](#motivation) | ||
- [Implementation](#implementation) | ||
- [Backwards Compatibility](#backwards-compatibility) | ||
|
||
## Abstract | ||
|
||
This RFC proposes using full [MSON][] syntax for description of URI parameters | ||
and HTTP headers. | ||
|
||
## Motivation | ||
|
||
Using MSON syntax for description of URI parameters and HTTP Headers will | ||
greatly help to unify the API Blueprint syntax and introduce reusability of | ||
URI parameters and HTTP headers. It will also greatly introduce the reusability | ||
of other data structures. | ||
|
||
In addition it will address many issues previously tracked on API Blueprint | ||
GitHub repository. | ||
|
||
### URI Parameters Issues Tracked | ||
|
||
This RFC addresses following issues: | ||
|
||
1. [Usage of data structures in Parameters](https://github.com/apiaryio/api-blueprint/issues/250) | ||
1. [Global query URI parameter](https://github.com/apiaryio/api-blueprint/issues/24) | ||
1. [Description of enumeration elements](https://github.com/apiaryio/api-blueprint/issues/119) | ||
1. [Array in parameters](https://github.com/apiaryio/api-blueprint/issues/240) | ||
1. [Minimum/Maximum values for URI Parameters](https://github.com/apiaryio/api-blueprint/issues/211) | ||
|
||
NOTE: This is going to be addressed once MSON introduces validation. | ||
|
||
### HTTP Headers Issues Tracked | ||
|
||
This RFC addresses following issues: | ||
|
||
1. [Parametric Headers Description](https://github.com/apiaryio/api-blueprint/issues/26) | ||
1. [Referenced HTTP headers](https://github.com/apiaryio/api-blueprint/issues/17) | ||
1. [Support for multiline syntax header](https://github.com/apiaryio/api-blueprint/issues/60) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We would need to think about multiple headers with the same key (apiaryio/api-blueprint#345). Especially with how that will work with inheritance and mixins. Example: ## Chapter [/TheBook/chapter{id}]
### View a chapter [GET]
+ Response 204
+ Headers
+ Include Pagination
+ Include Creatable
## Data Structures
### Pagination
+ Link (array)
+ `<http://example.com/TheBook/chapter1>; rel="prev"; title="previous chapter"`
+ `<http://example.com/TheBook/chapter3>; rel="next"; title="next chapter"`
### Creatable
+ Link: `<http://example.com/TheBook>; rel="create"; title="create a new chapter"` The user would probably expect all three link headers to be present in the response, the pagination mixing and creatable mixin. Normally mixins in MSON would override the key names and only |
||
|
||
In addition this issue is solved by this RFC: | ||
|
||
1. [Reuse headers and attributes](https://github.com/apiaryio/api-blueprint/issues/259) | ||
|
||
## Implementation | ||
|
||
### Parameters | ||
|
||
The implementation should assume the existing syntax for API Blueprint | ||
[URI parameters section][] is, in fact, an [MSON type declaration][]. | ||
|
||
The type being declared inherits from a *Parameters base type* unless specified | ||
otherwise. If another base type is specified it must inherit from the | ||
*Parameters base type*. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we sure about this? Why can't we simply allow any arbitrary MSON data structure of base type object? They are still valid. # Data Structures
## User (object)
+ name: pavan
# GET /users/{name}
+ Parameters (User)
+ Response 200 (application/json)
+ Attributes (User) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bear in mind I'm not very deeply knowledgeable (or experienced) in API Blueprint. That being said, It seems that requesting to inherit from a base parameter type means some for of multiple inheritance feature. It would introduce some possible type safety but in that case shouldn't there also be a Response base type and so on? Given that it should already possible for users to create a Parameter base type if they want to, then maybe it's best to lower the barrier to entry and allow any arbitrary MSON data structure as @pksunkara suggests. |
||
|
||
The *Parameter base type* may the [API Description Namespace][] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
[`Href Variables`][] type. | ||
|
||
The *Parameters base type* should be available as a type for use within any | ||
[data structures section][]. | ||
|
||
#### Example | ||
|
||
```apib | ||
# Resource [/resource/{p}{?q}] | ||
+ Parameters | ||
+ p | ||
+ q | ||
``` | ||
|
||
Assuming `Parameters` as the name of the *Parameters base type*: | ||
|
||
```apib | ||
# Resource [/resource/{p}{?q}] | ||
+ Parameters (My Parameters) | ||
|
||
# Data Structures | ||
## My Parameters (Parameters) | ||
+ p | ||
+ q | ||
``` | ||
|
||
### Headers | ||
|
||
The implementation of this RFC should introduce the use of MSON syntax in the | ||
[Headers section][]. Similarly to Parameters section this Headers section should | ||
be considered as [MSON type declaration][]. | ||
|
||
The type being declared inherits from a *Headers base type* unless specified | ||
otherwise. If another base type is specified it must inherit from the | ||
*Headers base type*. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar question to above. Do we need the Headers base type? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another argument against it is that it introduces a notion of global base types that are domain specific. They wouldn't fit in MSON, so you'd have to add them as a base type in maybe a MSON Apiary layer which seems like it would introduce a new moving part which makes the whole system just a little bit harder to understand (reading the MSON doc would not suffice to understand where the global base types come from). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To contradict this argument though. If there was a well understood transclusion mechanism (a la |
||
|
||
The *Headers base type* may the [API Description Namespace][] [`HTTP Headers`][] | ||
type. | ||
|
||
The *Headers base type* should be available as a type for use within any | ||
[data structures section][]. | ||
|
||
### Example | ||
|
||
```apib | ||
# Resource [/resource] | ||
## Retrieve [GET] | ||
+ Response 200 | ||
+ Headers | ||
+ Server: nginx | ||
+ `X-RateLimit-Remaining`: 4987 (number) - Remaining rate limit | ||
``` | ||
|
||
Assuming `Headers` as the name of the *Headers base type*: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You didn't actually use the |
||
|
||
```apib | ||
# Resource [/resource] | ||
## Retrieve [GET] | ||
+ Response 200 | ||
+ Headers (My Headers) | ||
|
||
# Data Structures | ||
## My Headers | ||
+ Server: nginx | ||
+ `X-RateLimit-Remaining`: 4987 (number) - The rate limit remaining | ||
``` | ||
|
||
## Considerations | ||
|
||
### Parameters base type constraints | ||
|
||
Using any type in as a member type in a descendant of Parameters base | ||
type may lead into problems while representing its value in URL. The | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But isn't the question of the representation of the data structure in the the URL orthogonal from the definition of the data structure itself? That seems to touch on some of the discussion here:
I guess that before abstracting that and making it pluggable, offering a couple of well specified serialisation formats should do the trick? For instance, Servant serialises arbitrary data types to a url parameter capture solution. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When it comes to arrays like you have in your example. URI Template already declares how this should be expanded based on the URI Template:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's about nested arrays? I.e. I have such structure
and I want to describe resource which accepts comment
How I can specify style of array in this situation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the objects and nested arrays serialisation is going to be complex and there is no set rules anywhere on how people do this. Each programming language & framework does it in it's own style |
||
implementation should consider using `application/x-www-form-urlencoded` | ||
together with [W3C HTML JSON form submission][] in the case where member type | ||
is of structured type base. | ||
|
||
Fore example: | ||
|
||
```apib | ||
# Resource [/resource{?q}] | ||
+ Parameters | ||
+ q (object) | ||
+ member1: one | ||
+ member2: two | ||
``` | ||
|
||
Would result into: | ||
|
||
``` | ||
/resource?q%5Bmember1%5D=one&p%5Bmember2%5D=two | ||
``` | ||
|
||
Additionally, a parser implementation may consider producing a warning in | ||
situations where member base type may cause an issue. | ||
|
||
### Headers base type constraints | ||
|
||
An implementation of a *Headers base type* descendant has to consider there may | ||
be multiple headers of the same name (key) defined. Additionally, if a member | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might want to ask users to use an array if there are multiple headers for the same name (key). # My Headers
+ Link (array)
+ first url
+ second url |
||
type of an *Haders base type* descendant is of a structured type a certain form | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
and parser warning should be considered similarly to Parameters base type. | ||
|
||
### Interoperability with other Data Structures | ||
|
||
It should be possible to use any MSON data structure – named type – as a member | ||
type of Parameters or Headers-based type. | ||
|
||
#### Example | ||
|
||
```apib | ||
# My Resource [/resource{?createdAfter}] | ||
+ Attributes | ||
+ created (Date) - Date when the resource was created | ||
|
||
## Retrieve [GET] | ||
+ Parameters | ||
+ createdAfter (Date, optional) - Retrieve only resources created after this date | ||
|
||
+ Response 200 (application/json) | ||
+ Headers | ||
+ Date (Date) - Date at which the message was originated | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And a named type whose base type is an list or an enum? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pksunkara then I agree with the idea of "header base type", which restricts value to primitive types or array of them. |
||
|
||
+ Attributes (My Resource) | ||
|
||
# Data Structures | ||
|
||
## Date (string) | ||
Date as defined in ISO 8601. | ||
|
||
### Sample | ||
Tue, 15 Nov 1994 08:12:31 GMT | ||
``` | ||
|
||
## Backwards Compatibility | ||
|
||
Introducing MSON as syntax for URI Parameters and HTTP headers description must | ||
be backward compatible with the existing syntax as it is. | ||
|
||
[MSON]: https://github.com/apiaryio/mson | ||
[URI parameters section]: https://github.com/apiaryio/api-blueprint/blob/master/API%20Blueprint%20Specification.md#def-uriparameters-section | ||
[Headers section]: https://github.com/apiaryio/api-blueprint/blob/master/API%20Blueprint%20Specification.md#def-headers-section | ||
[MSON type declaration]: https://github.com/apiaryio/mson/blob/master/MSON%20Specification.md#3-type-declaration | ||
[API Description Namespace]: https://github.com/refractproject/refract-spec/blob/master/namespaces/api-description-namespace.md | ||
[Href Variables]: https://github.com/refractproject/refract-spec/blob/master/namespaces/api-description-namespace.md#href-variables-object-type | ||
[data structures section]: https://github.com/apiaryio/api-blueprint/blob/master/API%20Blueprint%20Specification.md#def-data-structures | ||
[W3C HTML JSON form submission]: http://www.w3.org/TR/html-json-forms/#the-application-json-encoding-algorithm | ||
[HTTP Headers]: https://github.com/refractproject/refract-spec/blob/master/namespaces/api-description-namespace.md#http-headers-array-type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should be
greatly improve
instead ofgreatly introduce
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@geemus thanks I think my head was lost somewhere between the copy and paste 🙃 Any overall thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, copy/paste is one of my most prevalent errors for sure.
I still haven't played with MSON enough to have more specific feedback, but overall it seems really powerful/helpful to be able to do this. Being able to specify more about the headers/status is really lacking in pure json-schema (and previous to MSON it was harder to do params in blueprint). It seems like this could make both more accessible. Certainly look forward to seeing this land.