I have difficuties understanding REST principled for updating resource.
For example this response contains id of a resource
GET /users/5 { "user_id": 5 "first_name" : "John", "last_name" : "Doe", "minutes_active": 10
} And this assumes that an id of a resource is one stated in the url of a request
GET /users/5
{
"first_name" : "John",
"last_name" : "Doe",
"address":
{
"street" : "First Street 10",
"postal" : "0000",
"city": "Dublin"
},
"phones": [
{
"type" : "work",
"number" : "555 473-0000",
},
{
"type" : "home",
"number" : "555 473-0000",
}]
}
If i want to update only address I am thinking of using one of the following options.
1.
POST /users/5
{
"address":
{
"street" : "First Street 10",
"postal" : "0000",
"city": "Dublin"
}
}
2.
PUT /users/5
{
"address":
{
"street" : "First Street 10",
"postal" : "0000",
"city": "Dublin"
}
}
3.
PUT /users/5/address
{
"address":
{
"street" : "First Street 10",
"postal" : "0000",
"city": "Dublin"
}
}
Although POST is not idempotent it will always do the same work in this case (act as idempotent), as well as PUT. I somewhere read that this type of request is considered a partial update, and for this types of request we should use PATCH.
At this point I would like to avoid PATCH, and use some alternative.
Furthermore, if I isolate address as a separate resource in /users/5/address i could use PUT and it would be a solution that fully follows REST principles. But this could be a problem I a developer want to update fe. both phones and addresses using a single request.
If I would really want to use options 1 or 2 (and some huge systems such as zendesk, twitter are doing so), could I encounter any serious issues that I dont really see at this point?
The REST answer is: how would you do it with a web site?
You would GET the current representation of the user profile, and included int that representation would be a number of links, with semantic hints that cue the agent (you), as to what each link is for. You, knowing that your goal is to change the address, would follow GET that link, retrieving a representation that included a form, with a bunch of fields and a link instructing the client how to submit the form. So you would submit the form: a representation of the data would be sent (POST) to some resource that would in turn communicate with the domain to produce the side effect you wanted.
or...
You would GET the current representation of the user profile, and included int that representation would be a number of links, with semantic hints that cue the agent (you), as to what each link is for. You, knowing that your goal is to change the address, would follow GET that link, retrieving a representation of the address, which you would update in your favorite text editor. Then you would PUT the new representation back to the same resource, which update the servers copy of the address document.
So "REST principles" don't really care if you use POST or PUT -- as long as you use them in a way that is consistent with the RFC. REST cares a lot about the fact that you use POST and PUT the same way for all resources, and that the representations you send to the client instruct the clients behavior (rather than programming in a custom set of responses).
Furthermore, if I isolate address as a separate resource in /users/5/address i could use PUT and it would be a solution that fully follows REST principles. But this could be a problem I a developer want to update fe. both phones and addresses using a single request.
This isn't a problem - it has two different answers.
One possibility is that you always include the phones with the addresses, and let the agent decide what changes to make.
But the "advanced" answer is that you have two different resources -- one for editing the address along, and a different resource for editing the address and the phone number together. HTTP Resources are about the integration protocol between your domain and its consumers; if you want to introduce a new protocol, you just implement a new family of resources to support it, and then add links that advertise its existence.
GET /changeOfAddressForm?user=5
GET /changeContactDetailsForm?user=5