Example: JSON API for accounts

We plan to use JSON API at Hoodie and eHealth Africa projects.

At Hoodie, we are working on a hapi plugin that exposes a generic JSON API for all things account, like sign up, password reset, user management, etc. The hapi plugin will be part of the next Hoodie release, and will also be used in several eHealth projects. We are working on a client that will wrap the JSON API, too.

The JSON API spec can be found here: http://docs.accountjsonapi.apiary.io. As we are still very new to JSON API, it would be great if you could help us review it, just to make sure we don’t have any errors in reasoning. But we are happy about any kind of feedback, really :slight_smile:

I hope this also helps others who are getting started with JSON API to see another example of how JSON API is used in real-life projects.

Thanks :bouquet:


:question: Open Questions (I’ll keep these up to date)

  1. I just found out about the JSON Patch Extension. Are the PATCH routes in the spec invalid as they are right now?
  2. I think we could make use of the Bulk Extension, too. For one, when signing up, a user should be able to create both at once, an account and a profile. On top of that, it would be nice to allow to update / remove a bulk of accounts at once

Cool Thing! I just did a quick peek because I’m off for the weekend, but 2 things I saw on login:

  • you’re missing the 415 for wrong media type if the header isn’t present
  • in 409 you write “Invalid type provided, only supported type is ‘session’”. Please keep in mind that sessions as also ok. If it’s just your error message and not your implementation this is not so important

I will look into it on monday and return if I found more feedback to add.

Thanks @acid!

you’re missing the 415 for wrong media type if the header isn’t present

I have seen that in the specification, I don’t know what it means exactly: "Servers MUST respond with a 415 Unsupported Media Type status code if a request specifies the header Content-Type: application/vnd.api+json with any media type parameters " Can you provide an example?

in 409 you write “Invalid type provided, only supported type is
‘session’”. Please keep in mind that sessions as also ok. If it’s just
your error message and not your implementation this is not so important

As far as I understand it, both is allowed, singular and plural, but the API should be consistent about that. So for the Account API, I’d like to enforce singular everywhere, just because it looks more natural to me. I think accepting both, singular and plural, would be confusing.

@acid ping :bell:

I’d love to get more feedback on our API, it will be hard to change ones it’s in the wild, and it’s going to places right now, like a polio vaccination app used in Nigeria :slight_smile:

Hey @gr2m,

sorry for my delay!

I think it’s a hole in the jsonapi definition. But though the specification states “Clients MUST send all JSON API data in request documents with the header Content-Type: application/vnd.api+json without any media type parameters.” it should raise an error. The 415 is the way the implementation I’m currently using (GitHub - cerebris/jsonapi-resources: A resource-focused Rails library for developing JSON:API compliant servers.) handles this.

You’re right!

Best regards,
Daniel

The part that I don’t understand is “with any media type parameters”. Could you give me an example how such a request would look like, what these “media type parameters” are?

I think so. According to the rfc2616 Content-Type indicates the media type (See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html under 14.17 Content-Type). Http Client Libraries by default use something like Content-Type: text/html; in their generated headers.

In other words: A “media type parameter” indicates the MIME-Type of the request and/or excepted response.

Hey @gr2m

Sorry to jump in late here. I’ll try to look at your proposed spec soon.

But, just for clarification (and we should probably have an example of this on jsonapi.org), a media type parameter is an extra key–value pair that further specifies which content type is in use.

For example, text/html is a valid Content-Type, but so is text/html; charset=utf-8. In the latter, charset is the “media type parameter” (it parameterizes the text/html media type) and its value is utf-8.

So, what the spec is saying is that, if the client’s request includes something like:

Content-Type: application/vnd.api+json; someparameter=somevalue

or if it only lists parameterized versions of the JSON API media type in its Accept header, the server must reject the request.

This allows json api to add new media type parameters later without breaking things. For example, suppose we want to add an extensions parameter later, that the client or server can set to show which extensions are in use in the JSON API document. The content-type would then look like: application/vnd.api+json;extensions=.... So, it could be important that servers that don’t understand the extensions parameter reject requests that include it, so that the client knows that that part of the media type wasn’t understood.

@gr2m I just looked at your specification. It looks good overall! I’m also excited to see that you guys are using JSON API in the wild! Please keep posting here if you have questions, and add your companies to the list of who’s using json api if you’re allowed to.

I didn’t have a chance to think through all the edge cases, but they’re very small anyway (e.g. if someone tries to PUT /session when they’re already signed in, that probably should be a 200 OK rather than a 201 Created, since the resource already exists).

My most substantive piece of feedback, though, is that you’re design should probably use PATCH instead of PUT. The reason is that JSON API doesn’t define any semantics for PUT (so using the JSON API media type with PUT is technically not allowed) and PATCH will give you everything you need anyway.

@gr2m I just looked at your specification. It looks good overall!

Thanks so much for taking the time @ethanresnick, I really appreciate it! Glad you like it so far :smile:

I’m also excited to see that you guys are using JSON API in the wild! Please keep posting here if you have questions, and add your companies to the list of who’s using json api if you’re allowed to.

done :slight_smile: Who is using JSON-API? · Issue #825 · json-api/json-api · GitHub
We are not a company though, it’s an open source project. And we are not just guys :wink:

I didn’t have a chance to think through all the edge cases, but they’re very small anyway (e.g. if someone tries to PUT /session when they’re already signed in, that probably should be a 200 OK rather than a 201 Created, since the resource already exists).

The thinking is that PUT /session will always give you a new session id. You don’t send any authentication header with that request so the server can’t know if the client already has a valid session or not.

My most substantive piece of feedback, though, is that you’re design should probably use PATCH instead of PUT. The reason is that JSON API doesn’t define any semantics for PUT (so using the JSON API media type with PUT is technically not allowed) and PATCH will give you everything you need anyway.

Oh wow, was that always the case? I’m quite sure that when we looked at it, the spec said that PUT can be used instead of POST to create a resource. And as far as I know, if you know the final URL of the resource you want to create, than PUT is the correct http verb to use. We use PATCH for updating accounts and profiles, but I wouldn’t use it to create the session. If PUT is not specified in JSON API, then I’d either add it to the specification :slight_smile: or use POST as a fallback I think …

You’re right. Thanks!

Right. My point about returning 201 each time, though, had to do with this:

In HTTP terminology, a URI has a one-to-one correspondence with a resource (i.e., the concept that the URI denotes). So /session should always represent the same resource. So, unless the resource identified by /session is deleted or disappears, it seems strange that it could be “created” more than once, right?

Now, this may be too small a point to matter. But, if it does bother you, it might be one more reason to look into POST or think about other structures.

I think you’re right that the spec changed it’s position on this at some point. As a theoretical note, though, PATCH can also allow resource creation like you’re describing. Here’s the text from the PATCH RFC:

If the Request-URI does not point to an existing resource, the server MAY create a new resource, depending on the patch document type (whether it can logically modify a null resource) and permissions, etc.

However, JSON API still hasn’t settled on whether its PATCH format allows for resource creation, so for now I think you’re right to avoid it, actually. I guess that means falling back to POST?