Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP POST requests in a RESTFul HATEOAS API

Tags:

rest

hateoas

I'm writing a RESTful HATEOAS API. I have compound entities which I have to GET, POST and PUT. The GET part is easy, and has lots of examples. The response contains the entity's primitive attributes, and links to nested entities. For example:

{
 "id":"2",
 "firstName":"Brad",
 "lastName":"Pitt",
 "balance":1234.5,
 "transactions":"http://localhost:8080/jersey-poc/api/v1.1/account/1/transactions",
 "self":"http://localhost:8080/api/v1.1/account/1",
 "accountType":"http://localhost:8080/api/v1.1/account/1/accountType"
}

The problem arises when I want to create or modify the account. I need to associate the account with an accountType. I can send the a POST request such as the following: {"firstName":"Michael","lastName":"Jackson","balance":300.0,"accountTypeId":5}
but that would break the HATEOAS paradigm. What is the best practice to POST/PUT compound entities?

like image 527
Amir Kost Avatar asked Feb 14 '13 08:02

Amir Kost


People also ask

What is POST request in REST API?

The first REST API request in a session must be a sign-in request. This is a POST request that sends the user credentials in the body of the request. Because this is a POST request, the request must include the Content-Type header. You can send your the body of the request block as XML or JSON.

Can RESTful web services use HTTP POST method?

The HTTP verbs comprise a major portion of our “uniform interface” constraint and provide us the action counterpart to the noun-based resource. The primary or most-commonly-used HTTP verbs (or methods, as they are properly called) are POST, GET, PUT, PATCH, and DELETE.

How do I make a POST request REST?

To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.


1 Answers

There's nothing particular about that payload that would go against HATEOAS; the only real problem is that the accountTypeId isn't very discoverable. (Magic IDs are always better off being mapped into short descriptive strings; think of them as being like an enumeration.) One of the key things to remember when working to a HATEOAS model is that the entity that the user POSTs does not need to be exactly the entity that creates the resource; you can modify it, annotate it, translate it. It should still be conceptually the same, but that's totally different to being identical. (Adding IDs and creation timestamps would be excellent examples of how extending would be totally reasonable.)

To me it sounds like your real problem is that you need to reconsider just what information clients should submit when doing a POST, and how you intend to tell clients that they should submit that information when doing the POST. Myself, I quite like using XML for upload here, because I can easily tell clients that their POST payloads should conform to a particular schema (and both XML Schema and RELAX NG are rich enough for me to describe the constraints). I'm sure that's not the only way to do it.

like image 147
Donal Fellows Avatar answered Oct 22 '22 17:10

Donal Fellows