Open RubenVerborgh opened 3 years ago
I say "sometimes we do, sometimes we don't". :-)
In the case of successful requests with no content, there are quite a few to choose from, 200
, 204
and 205
, and it is quite OK to use either. For resources that has just been created, it is best practice to use 201
, but you could use one of the above too. It makes sense to be quite lenient.
In other cases, it would be just require a lot of extra effort on the implementers to find the right one, and I think that we should provide them with this.
Also of concern is that other specs should generally just need to reference the protocol spec for HTTP-specific stuff, and that includes the status codes, and so, I think in many cases, it makes sense to be clear about it.
I would be careful about over-specifying such things. Providing guidance is great, but if the Solid protocol is combined with other, future, specifications, there may be cases where you encounter conflicts. For instance, Solid may require a 204 while another spec may require a 205. It is much better to require a 2xx response and recommend a particular code. The same applies to 4xx category codes.
@acoburn I think a recommendation would be fine too, just getting some precise guidance would save dev time and create a more consistent ecosystem for apps to talk to.
The Solid Protocol works within the framework of HTTP (RFCs). The Protocol either tries to consistently echo RFC codes or recommends particular codes ones when describing specific behaviour. And there may potentially be wilful violations, but that tends to happen as a last resort in specific context when building on other (non-RFC) specifications.
It is worthwhile for the Protocol to allow sufficient variance so that implementations can accommodate specific needs without jeopardising interoperability. A conforming implementation follows the requirements trail all the way to the end.
I agree with concerns on extensibility and avoiding conflicts when specifications are combined.
https://github.com/solid/specification/issues/14#issuecomment-683480525 (WIP) hints at using codes sensibly (before the tables) eg. "Then, 2xx or 4xx (besides 401, 403) can be used." I consider the codes in the table as good/safe for implementations - but they shouldn't be taken as fixed and only way to achieve conformance. Some of those cases can legitimately use different codes. The original purpose of the table was to highlight "least information leakage" eg. 403 is perfectly fine/useful when need to raise forbidden, whether that's due to access controls, identifiers, or something else. But that doesn't mean implementations can't for example use 404. The comment in fact highlights when 404 may even be more interesting/useful of a response than a 403 in some cases (if the server chooses).
This applies to 3xx as well. We say 307, 308 when we really need to, but in the general case, 301, 302, 307, 308 for example, would be acceptable.
Depending on context, 200, 201, 204, 205 may be most appropriate but 202 and 203 would also be acceptable. The first set of codes is relatively more specific to the operation than the second set of codes.
We could list all valid codes but we'll just be repeating other specifications. Prefer to keep the Protocol lean. Follow DRY.. avoid potential mistakes..
Besides the case of requiring particular codes for specific behaviour, the Protocol should note that implementations (servers) use the most appropriate code within the boundaries of relevant specifications. This is already implied (IMHO) but okay to note. Ditto clients and applications expecting relevant codes. The Protocol should not note that any 2xx, 3xx, 4xx, 5xx is appropriate at all times - easy to fall into this trap.
Here's some implementation information based on Solid-Shell scripts run against CSS, NSS, ESS, and Solid-Rest. This is by no means exhaustive. Success was only tested when no pre-existing resources existed.
These are different between the servers:
CSS NSS ESS Solid-Rest
205 201 201 201 PUT success
403 403 400 403 POST to auxiliary resource
205 200 204 200 PATCH success
205 409 204 409 PATCH delete non-existent triple <-- someone is wrong
409 500 204 409 PATCH container <-- someone is wrong
205 200 204 200 DELETE success
These are the same in all four implementations
200 GET on success
200 HEAD on success
201 POST on success
204 OPTIONS on success
400 PUT/POST/PATCH on no content-type supplied
400 PATCH on syntax error in patch
400 PATCH on syntax error in resource to be patched
404 DELETE/GET/HEAD on item not found
409 DELETE on container not empty
I'm not sure this issue serves a purpose. There are most certainly cases where valid status codes will be enumerated, and there are cases where the details are covered by e.g. HTTP RFCs. I'm not sure what else would be actionable from this issue.
Perhaps not much of an issue for spec writers, but really helpful for implementer to know. May I suggest that whenever a specific code or one of several codes is required, that it be so stated and when any 2xx response is okay, that also be stated. And what would be really helpful is a single page somewhere listing all of these that have been decided so that implementers are not left to pick through dozens of issues to figure out what is expected.
Yeah, I certainly recognize that, and since test suite will necessarily contain those status codes, there will be an authoritative source for them.
My hunch (having written a lot of the NSS implementation) is that that will be sufficient, you go with what is intuitive to you until a test fails, then you check out why it failed, and you'll see the authoritative answer at that point. I hope the spec won't be so weird there will a lot of exceptions from general intuition of devs :-)
If that expectation fails, there are three approaches, 1) fix the spec to align with developer intuition, 2) Just spec out all the weirdness in the spec clearly and 3) create a best practices document with all the status code. Or perhaps a mix of them. I think 1) would be quite appropriate. :-)
There was some discussion in https://github.com/solid/conformance-test-harness/issues/155 and following that, my suggestion is that we resolve this issue with the conclusion is that we sparingly bring upstream spec requirements (importantly HTTP) into the Solid Protocol spec, but that we create a comprehensive test suite that authoritatively details response codes, so that developers will be able to see if their implementation is compliant and since we link to requirements, also quickly see why.
I've been combing through some related issues, and feel that this one has a strong consensus that as a general rule the Protocol can sparingly recommend specific status codes, or require status categories.
@csarven, can we close this as part of the v0.11 milestone? Should we document the conclusion somewhere?
I will elaborate further on my comment in https://github.com/solid/specification/issues/288#issuecomment-888102563 .
tl;dr: Kjetil's "sometimes we do, sometimes we don't" encapsulates the essence of the discussion.
My interpretation here, as well as the intention behind SP v0.10 and other Solid TRs, along with existing test cases and implementations, suggests that adherence to "exact status codes" is not always the sole focus.
There are numerous scenarios not explicitly addressed in the SP where a status code may deviate from what's explicitly stated in requirements. Non-normative sections like Considerations or Notes can bring attention to specific cases for implementers to consider. Even a single requirement may encompass multiple test cases, revealing situations where different status codes are appropriate.
Real-world deployments may differ. Exceptions are inevitable.
While interoperability can be assessed based on behaviour, adherence to specifications, and implementation reports, achieving flexible deployments extends beyond adhering strictly to predefined status codes. Put differently, Solid clients/applications are not the only software interacting with Solid servers on the Web. HTTP messages are processed by various types of software, and servers may need to use different status codes than those outlined in the SP. I want to be clear that, I'm not saying that servers can do whatever or returning a random status constitutes interoperable. It is all within reason and the exceptions are understood.
Putting aside clearly conflicting scenarios, for Solid implementations to coexist, be compatible with, or interoperate with other product classes defined by different specifications, some flexibility in status codes is reasonable.
HTTP clients are expected to understand status categories (x00).
That said, when we try to put the "smarts" on Solid applications, I'd expect them to grok just a bit more than what a specification says. (As opposed to flipping the table and walking away from the user.)
I don't think we need to say something about all this in the specification, but if need be, I can put together a short paragraph for v0.11.
I don't find 205 to be an appropriate response to a PUT request. Here is why: the purpose of PUT is to create/update the resource state, not for the purpose of 'reset[ting] the "document view"'. It does not communicate anything particularly useful to the client because even if client were to reset the document view, they can't clearly tell whether the request resulted in creating or updating a resource. 205 is unrelated to the semantics of a PUT request and inappropriate for the the context, even though request methods are not tightly coupled with status codes. Clients can categorically understand what 2xx-5xx entails but the successful expected status codes that a server should returned are as mentioned: 200, 201, 204. The Solid Protocol is not changing or wilfully violating that in any way. Servers responding with something else will at best confuse the clients. Regarding testing, a test could be included to cover edge cases for other 2xx codes besides those mentioned but they do not particularly inform us of anything useful - there'd need to be additional tests diving into super-edge cases about "document view" tied to the semantics of a given resource but that's already ventured off.
As far as HTML forms go, which is the typical / dominant case for data entry on Web applications, its method does not include PUT: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fs-method . So, form method="POST" with 205 could work (based on specs). I still don't see a strong connection between PUT and 205. PUT is intended to be sharp - something created or updated is communicated. If a server is returning 205 it means that it has good knowledge of the resource semantics or following the hints in the request, but that is not at all the case for any / generic resources. Again, returning 205 to PUT is not particularly helpful. For example, say an application wants to create a container, and the user specifies the name which eventually normalises to a URI and then PUT is requested. If the response to that is 205, what should the application do? Reset the document view without actually getting a clear signal on whether the container was created or not. All meanwhile, that's exactly what the application wants to know - did the container just get created and let the user know, or did it get rejected for whatever reason (e.g., unable to attempt to re-create an existing container with existing resources).
We for sure would prefer mandated codes to return in all cases to reduce head-scratching about what to send.