Some questions about {json:api}

Hi, just starting reading up on JSON:API after getting increasingly frustrated with the lack of sufficiently robust standards on our how best to design HTTP+JSON-based APIs to handle all the needs of modern applications. I quite like what I’ve seen so far from reading through the jsonapi.org site, but some questions:
a) why not mandate a specific ‘date’ format? The lack of a good standard for JSON in this regard has been the source of much grief to many of us. For instance I quite like the Date(nnnn) format that a few APIs use, but generally have stuck to ISO 8601 based formats even though there’s significant variation among many commonly used libraries as to how exactly how such dates should be parsed or formatted.
b) the guidelines on returning HTTP error codes seem like they could be clearer. In particular - if the URL refers to a valid endpoint supported by the server but the particular requested resource doesn’t exist, should 401 be used - even if it’s something in the query string parameters or POST body that might be referring to a non-existing entity? And what HTTP status code should be used if a server is able to partially fulfil a POST request, making certain modifications to server state but not others. In fact the current specification disallows having a response with both ‘data’ and ‘errors’ in the response - but for instance, I work with some APIs that support bulk-creation/update requests, where it’s possible that some entities are created and others not, and that return both data for the created entities (ids etc.), and errors for the ones that can’t be created. How would these work in JSON:API?
c) I’d especially like to see guidelines on URLs/HTTP methods for operations that aren’t typical CRUD-type operations. For instance, payment gateway type APIs where a common operation is to authorize a payment - there’s no resource being created, read, updated or deleted in any meaningful sense. What would be the ideal {json:api} URL for such an operation? Another common example is APIs that are such a particular type of ‘update’ where extremely restricted operations are possible and where the REST-like convention of doing a POST or a PATCH to the resource with just the updates in the message body sits awkwardly (e.g. a particular resource might support the concept of being ‘locked’ or ‘unlocked’, but to update to ‘unlocked’ requires the user to specify particular additional information that isn’t intended to become part of the persisted state of the resource).
d) what’s the rationale behind allowing hyphens in JSON:API field names? I’ve used a few APIs that do just that and the complications it raises with backend serialization/deserialization is always a pain: very very few programming languages support hyphens in names.
e) are there any planned recommendations on how servers should deal with field names they don’t recognise? Personal experience strongly suggests it’s far better for servers to reject JSON with unrecognised field names (as it’s most likely that whoever programmed the client is expecting the field to be read by the server).
f) any planned recommendations on how best to support data-types such as Enums or UUIDs?
g) any consideration given to JSON schemas, whether via swagger or other means, and how they’d work with JSON:API?
h) any planned recommendations on API security?
i) perhaps most controversially - is it too late to be so focused on JSON when Protobuf and other binary formats might end up making it obsolete?

Thanks and sorry if any of this has already been debated to death here.
Dylan

a. I don’t think this spec is the place to mandate the content of attributes as there are no semantics in the spec that rely on dates. You might want to use an OAS 3.0 spec to specify this kind of requirement – which is RFC 3339, a profile of ISO 8601.

b. I think, as a RESTful spec, that the usual meanings of HTTP status codes apply here. I haven’t seen a problem with this in practice. The spec does not support bulk operations, so there’s no need for the complication of both data and errors in the same response. There was a draft extension for bulk but it died on the vine. See the extensions tab at jsonapi.org.

c. Just as jsonapi is opinionated, so am I: Truly RESTful applications only use HTTP verbs with resources that are generally plural nouns for collections. If you think you need the equivalent of a SOAP method invocation, recast it as a new resource with attributes that track the state of the transaction and whatever business rules that trigger insider your server based on those attribute values. Using relationships you can tie that resource to the one it is related to.

d. The JSON spec allows pretty much anything as a mapping key; there’s no expectation that you’ll map a key to a direct programming language variable. For example, in Python, I would use something like result['data']['attributes']['start-date'] to reference the start-date attribute in this response:

{
    "data": {
        "type": "my-type",
        "id": "00452381-cb1d-4198-a029-9bcc6d838a44",
        "attributes": {
            "name": "Data Services",
            "version": "BI4.2",
            "start-date": "2012-03-01"
        }
    }
}

Some libraries (like Django REST Framework JSON API – DJA) will automatically do camel-, snake- etc. case conversions for you. And ORM client libraries will also do the mappings. Having said that, in DJA, the mappings are usually constrained to Python’s variable names, so you wouldn’t see a hyphen.

e. I believe that is why jsonapi has a rich error object definition.

f. See above re: Dates.

g. OAS 3.0 is able to represent jsonapi. This is actually WIP for the DJA project: automated OAS 3.0 schema generation.

h. That seems out of scope for jsonapi. Security specification is already present in OAS. Our jsonapi apps use OAuth 2.0/OIDC via the Authorization header.

i. Hahaha. Seems the big competitor is actually graphql. This is my go-to argument for jsonapi: https://www.jeremiahlee.com/posts/json-api-your-smart-default/. But stuff is always changing.

All of the above are my opinions based on being a consumer of the spec. I’m sure some flames will ensue, as I’ve previously been flamed here.

Thanks for the response, having read a bit more since, including the FAQ and your response I think unfortunately {json:api} doesn’t quite satisfy what I was hoping for, at least in its current incarnation. Which is fine, but it does seem there’s still a gap waiting to be filled in this regard.

I’ve been playing around with my own .NET core implementation of the JSON.API as a learning exercise more than anything, and the first thing I wanted to add to my sample project was a search API.
Given GET /FooBars/ returns a response with a list of FooBar objects, and GET /FooBars/123 returns a response with just the FooBar with ID 123, it seemed to me that a logical endpoint for a search API would be GET /FooBars/search?query=..., returning the same structure response as GET /FooBars/ - but this could be a problem if the ID could be any string at all (including the word ‘search’). Interestingly the default .NET Core API routing handles this without complaint, but it does mean you would never be able fetch a entity with ID=“search”. I suppose this is an example of the sort of guidelines I was hoping to see re APIs that are not just basic CRUD.

I also tried out an example of an “update”-like operation for which “PATCH” doesn’t quite make sense to me - specifically I wanted to expose the operation “open” on my entity type, which would update the “openedDate” property to the current date/time, or cause an error if the entity was already opened.
Hence I exposed POST /FooBars/{id}/open as an endpoint, but it doesn’t take any body at this point. It does return back the same structure PATCH does though, so would there be an argument for using PATCH as a verb in this case?