Skip to content
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

Consider relaxing some MUSTs #2

Closed
steveklabnik opened this issue May 4, 2013 · 15 comments
Closed

Consider relaxing some MUSTs #2

steveklabnik opened this issue May 4, 2013 · 15 comments
Labels

Comments

@steveklabnik
Copy link
Contributor

One from HN:

That's great to hear. One particular example which I found needlessly strict is this:

    The request MUST contain a Content-Type header whose value is
    application/json.  It MUST also include application/json as the only or
    highest quality factor.

It makes sense for fully compliant implementation to have those headers, but they way I understand MUST here is that a server would reject any request without them.

https://news.ycombinator.com/item?id=5656097

@b
Copy link

b commented May 6, 2013

Every MUST is one less opportunity for implementations to be compliant and incompatible. Please keep the MUST.

@reinh
Copy link
Contributor

reinh commented May 7, 2013

The MUST will not be a barrier to compliant implementations because they will do what the spec says. It will also not be a barrier to non-compliant implementations because they won't do what the spec says.

👍 for keeping the MUST

@mamund
Copy link

mamund commented May 7, 2013

note that each MUST is a promise forever. no future mod, update, or bug fix would be allowed if it ran counter to an existing MUST. aim for SHOULD and MAY, limit MUST to bare minimum. adding MUSTs puts limits on an unknown future - that's rarely a smart idea.

to encourage implementations to follow you specs closely it is common to use the following in your documentation:

An implementation is not compliant if it fails to satisfy one or more of the MUST or REQUIRED level requirements. An implementation that satisfies all the MUST or REQUIRED level and all the SHOULD level requirements is said to be "unconditionally compliant"; one that satisfies all the MUST level requirements but not all the SHOULD level requirements is said to be "conditionally compliant."

@b
Copy link

b commented May 7, 2013

"adding MUSTs puts limits on an unknown future - that's rarely a smart idea."

No, adding MUSTs make the lives of implementors easier and eliminates opportunities for incompatible implementations. That unknown future is properly handled in a protocol through versioning and extension mechanisms that allow entirely optional additional behavior, not through a proliferation of MAYs.

For example, look at how few MAYs are in RFC2616 and how most of them relate to client behavior in the face of MUST and SHOULD behaviors on the server. That is the result of careful protocol design and painful experience. Postel's Law in action: http://en.wikipedia.org/wiki/Robustness_principle

@mamund
Copy link

mamund commented May 7, 2013

My count of RFC2119 words in RFC2616 (including initial description of the words):

  • MUST/SHALL/REQUIRED = 353
  • SHOULD/RECOMMENDED = 256
  • MAY/OPTIONAL = 187

There is no incentive to build servers that screw up people's data. You don't need to beat everyone over the head w/ MUSTs. Just help them out w/ guidance w/ SHOULD (to stay compliant) and advice w/ MAY.

And since you're ref'ing RFC2616, this section on the use of If-Match on PUT should be considered:
A request intended to update a resource (e.g., a PUT) MAY include an If-Match header field to signal that the request method MUST NOT be applied if the entity corresponding to the If-Match value (a single entity tag) is no longer a representation of that resource. This allows the user to indicate that they do not wish the request to be successful if the resource has been changed without their knowledge.

@brettgerry
Copy link

Good point, mamund. One SHOULD in RFC2616 is relevant here:
If an Accept header field is present,
and if the server cannot send a response which is acceptable
according to the combined Accept field value, then the server SHOULD
send a 406 (not acceptable) response.

I would tend to take advantage of this SHOULD when designing an API that may be used by tens of thousands of developers, many with no previous experience using a ReST API. If all they are doing is trying to accomplish a task like sending a text message, I am going to return a response of a default representation even if they don't send an accept header with application/json.

If given the choice of rigid adherence to a standard versus API ease of use, I will choose the latter. A standard that gives some flexibility with SHOULD's is one that I am more likely actually follow.

@rkh
Copy link

rkh commented Nov 12, 2013

For this specific example I would suggest keeping it regulated. Considering that the content type has been changed now and certain clients might ask for application/json, I propose modifying the requirements as follows:

  • If the request's Accept header permits "application/vnd.api+json", a server MUST reply with the Content-Type "application/vnd.api+json" (or choose a different representation also conforming with the Accept header).
  • If the request's Accept header does not permit "application/vnd.api+json", but permits "application/json", a server MAY still reply with a JSON API resource and MUST set the Content-Type to "application/json". A server MAY choose to reply with HTTP status 406 "Not Acceptable". A server MAY also reply with any other JSON based representation (or anything conforming with the Accept header).
  • If the request's Accept header does not permit any of the above, a server MUST NOT send a JSON API reply. It SHOULD reply with HTTP status 406 "Not Acceptable". It MAY instead reply with any other representation that is acceptable.

@mamund
Copy link

mamund commented Nov 13, 2013

"If the request's Accept header permits..." : the client controls this string, not the server. and clients can add whatever media types they wish whether servers understand them or not.

what you might be trying to say is something like this: "If the server can represent as resource in the application/vnd.api+json format AND the client includes the application/vnd.api+json identifier in the Accept header THEN the server MUST respond using the application/vnd.api+json media type."

Personally, I think this is over-constraining. I see no reason to over-ride the HTTP spec which uses the SHOULD word (not MUST) in directing servers on how to respond to the Accept header.

@b
Copy link

b commented Nov 13, 2013

json-api is a protocol defined on top of http. by definition, it must
specify exactly how to use the mechanisms defined in http. precise
definitions of the correct behaviors for clients and servers simplify
implementation, testing. and interop.

if you just say "do whatever http says you can", then json-api is
superfluous. there is a need for this sort of application protocol exactly
because http is a big bag of mechanisms from which people have to choose.
using MUST is one less choice everyone has to make to get their application
to work. let's do that.
On Nov 13, 2013 5:05 AM, "Mike Amundsen" notifications@github.com wrote:

"If the request's Accept header permits..." : the client controls this
string, not the server. and clients can add whatever media types they wish
whether servers understand them or not.

what you might be trying to say is something like this:
"If the server can represent as resource in the application/vnd.api+json
format AND the client includes the application/vnd.api+json identifer in
the Accept header THEN the server MUST respond using the
application/vnd.api+json media type."

Personally, I think this is over-constraining. I see no reason to over-ride
the HTTP spec which uses the SHOULD word (not MUST) in directing servers on
how to respond to the Accept header.


Reply to this email directly or view it on GitHubhttps://github.com//issues/2#issuecomment-28392371
.

@mamund
Copy link

mamund commented Nov 13, 2013

Constraining the application-level protocol (json API) is great.
Constraining the network-level protocol (http) is a mistake.
On Nov 13, 2013 10:38 AM, "Benjamin Black" notifications@github.com wrote:

@b
Copy link

b commented Nov 13, 2013

making specific choices about which http mechanisms to use and how exactly
to use them is how a protocol, like json-api, is defined.
On Nov 13, 2013 12:55 PM, "Mike Amundsen" notifications@github.com wrote:

Constraining the application-level protocol (json API) is great.
Constraining the network-level protocol (http) is a mistake.
On Nov 13, 2013 10:38 AM, "Benjamin Black" notifications@github.com
wrote:

json-api is a protocol defined on top of http. by definition, it must
specify exactly how to use the mechanisms defined in http. precise
definitions of the correct behaviors for clients and servers simplify
implementation, testing. and interop.

if you just say "do whatever http says you can", then json-api is
superfluous. there is a need for this sort of application protocol
exactly
because http is a big bag of mechanisms from which people have to
choose.
using MUST is one less choice everyone has to make to get their
application
to work. let's do that.
On Nov 13, 2013 5:05 AM, "Mike Amundsen" notifications@github.com
wrote:

"If the request's Accept header permits..." : the client controls
this
string, not the server. and clients can add whatever media types they
wish
whether servers understand them or not.

what you might be trying to say is something like this:
"If the server can represent as resource in the
application/vnd.api+json
format AND the client includes the application/vnd.api+json
identifer
in
the Accept header THEN the server MUST respond using the
application/vnd.api+json media type."

Personally, I think this is over-constraining. I see no reason to
over-ride
the HTTP spec which uses the SHOULD word (not MUST) in directing
servers
on
how to respond to the Accept header.


Reply to this email directly or view it on GitHub<
https://github.com/json-api/json-api/issues/2#issuecomment-28392371>
.


Reply to this email directly or view it on GitHub<
https://github.com/json-api/json-api/issues/2#issuecomment-28404660>
.


Reply to this email directly or view it on GitHubhttps://github.com//issues/2#issuecomment-28432921
.

@rkh
Copy link

rkh commented Nov 13, 2013

"If the request's Accept header permits..." : the client controls this string, not the server. and clients can add whatever media types they wish whether servers understand them or not.

what you might be trying to say is something like this: "If the server can represent as resource in the application/vnd.api+json format AND the client includes the application/vnd.api+json identifier in the Accept header THEN the server MUST respond using the application/vnd.api+json media type."

Personally, I think this is over-constraining. I see no reason to over-ride the HTTP spec which uses the SHOULD word (not MUST) in directing servers on how to respond to the Accept header.

What I'm trying to say: If the server decides to reply with a json-api repsonse, and the accept header includes application/vnd.api+json (or any wildcard version that would match it), the server MUST/SHOULD set the content type to application/vnd.api+json.

@mamund
Copy link

mamund commented Nov 13, 2013

@rkh:

aahhh!

then i'd say just that. IOW, don't write it in terms of how to use HTTP features, write it as you just did, in terms of how to use JSON API features.

@mamund
Copy link

mamund commented Nov 13, 2013

@b

FWIW, my advice is to not author a new protocol on top of the HTTP protocol. Instead focus on authoring a new media type that can work with one or more protocols. there is huge oppty here to create a single format that works in many places now and in the future.

frankly, i'd like to see this message model appear not just in HTTP, but also CoAP and MQTT going forward. if you spend a great deal of time fiddling w/ HTTP details and baking them into this spec, you'll be forever tied to that one protocol and will be increasing the chances of running afoul of mis-interpretations at the network-level and even possible changes at the network level over time.

just my $0.02.

Cheers.

@gr0uch
Copy link
Contributor

gr0uch commented Nov 13, 2013

@mamund it's already constrained to the HTTP protocol by taking advantage of HTTP verbs and HTTP headers, so your idea might be overly optimistic. I think it might be interesting as a proof of concept to use the JSON API media type over another protocol like WebSockets, but you'd have to invent new vocabulary to do that.

steveklabnik pushed a commit that referenced this issue Mar 23, 2015
tiagopog added a commit to tiagopog/json-api that referenced this issue Mar 11, 2016
cosullivan pushed a commit to cosullivan/json-api that referenced this issue Sep 9, 2016
Added jsonapi-converter link to the list of client libraries

removes trailing comma from JSON object

Update index.md

Add link to JsonApiParser library.

Include JSONAPI::Utils gem in the list of implementations

Include JSONAPI::Utils gem in the list of implementations json-api#2

Remove redundant gem name in the server libraries list

Add Morpheus for Java client libraries

updating from the upstream repository

added the hypermedia.cainosullivan.com to the examples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants