Recommended POST format

Not applicable

When reading the excellent eBook Web API Design: The Missing Link, I stumbled upon a problem.

In the chapters "Designing Representations" and "More on Representation Design", the author argues to include a "kind" property, a "self" link and for related resources a link to those resources.
Example:

{
  "self": "https://dogtracker.com/dogs/12345678",
  "id": "12345678",
  "kind": "Dog"
  "name": "Lassie",
  "furColor": "brown",
  "owner": "https://dogtracker.com/persons/98765432"
}

This is pretty neat.

While this works great for GETting a resource, how should this be formatted when POSTing a resource?

The "self" doesn't make sense. But what about the "kind" and even the "id"?
Also, the "owner" should probably be indicated just with its id?

Are there any recommended practices for formatting JSON for a POST request as well?

Solved Solved
0 4 165
1 ACCEPTED SOLUTION

Not applicable

I agree that it does not make sense to include "self" in a POST that is performing a create — the server will allocate the URL for the new resource.

In my own designs, I never include an "id" property in resources. From the point of view of the API client, the value of "self" is the resource id (URI stands for uniform resource identifier). In my opinion, when you include an "id" property in a resource you are effectively leaking your implementation detail through the API — the value of "id" is probably a database table primary key.

I think it is much better for the value of "owner" in a POST to be the URL of the owner. Later in the book, there is a discussion of how to handle the case where the owner can be either a person or an institution. If you only include an owner "id" in POST, this scenario creates a challenge — how do you indicate whether the value of "id" is the id of a person or the id of an institution? If the value of "owner" in a POST is a URL, you have no such problem. I believe it is better if every id in an API is a URI, with HTTP URLs being by far the most useful type of URI.

In general, I find that there are 3 common categories of property in the JSON representation of a resource — read-write, read-only, and write-once. In this example, "self" is read-only. "kind" is write-once. "name", "furColor" and "owner" are read-write. JSON schema can express read-only, but I'm not aware of a standard language (other than natural language) that can express write-once, even though it is very common.

View solution in original post

4 REPLIES 4

Not applicable

I agree that it does not make sense to include "self" in a POST that is performing a create — the server will allocate the URL for the new resource.

In my own designs, I never include an "id" property in resources. From the point of view of the API client, the value of "self" is the resource id (URI stands for uniform resource identifier). In my opinion, when you include an "id" property in a resource you are effectively leaking your implementation detail through the API — the value of "id" is probably a database table primary key.

I think it is much better for the value of "owner" in a POST to be the URL of the owner. Later in the book, there is a discussion of how to handle the case where the owner can be either a person or an institution. If you only include an owner "id" in POST, this scenario creates a challenge — how do you indicate whether the value of "id" is the id of a person or the id of an institution? If the value of "owner" in a POST is a URL, you have no such problem. I believe it is better if every id in an API is a URI, with HTTP URLs being by far the most useful type of URI.

In general, I find that there are 3 common categories of property in the JSON representation of a resource — read-write, read-only, and write-once. In this example, "self" is read-only. "kind" is write-once. "name", "furColor" and "owner" are read-write. JSON schema can express read-only, but I'm not aware of a standard language (other than natural language) that can express write-once, even though it is very common.

You're completely right regarding the "id".

Regarding the owner: including an URI makes sense, but I guess it will be difficult for the backend to check if the owner really exists (needs an id, and hence parsing). Or how would you solve that?

How the implementation of "dogs" checks the URI of an "owner" depends on your overall implementation design. If your implementation is monolithic, you can teach the dogs implementation to parse the owner URI. If the owner implementation and the dogs implementation are part of the same monolith, there is probably already a convenient function/method/procedure from the owner implementation that can be called. We all used to write monoliths this way. For the last few years, I have been writing implementations in a "micro-services" style (a poorly-defined term, I know, but I don't have a better one). The way my dogs implementation would check the validity of the owner URI is by doing a GET on the URI. Some validation of the URI would be necessary for robustness to protect against badly-formed URIs, but the final validation would be done by the owner implementation(s) in response to GET. The URI validation to make sure that the owner URI is plausible is generic code in a library used by all the micro-services to verify proposed links. The GETs (and other requests) between my micro-services follow an optimized internal path that does not require them to go back out to the internet, but they are "real" HTTP requests.

I'm in the microservices camp 🙂 Thanks for the clear answers!