How to get readable access to an editable resource in REST style?

I am well acquainted with the principles of REST and read the relevant dissertation, Wikipedia entry, a bunch of blog posts and StackOverflow questions on this question, but still have not found a direct answer to the general case:

I need to request a resource to display. Depending on the state of the resource, I need to display either a read-only view or an editable view. In both cases, I need to GET a resource. How to create a URL to get a read-only or editable version?

If my user follows the link to GET /resource/<id> , that should be enough to tell me that he needs a read-only view. But if I need to create an editable form, what does this URL look like? GET /resource/<id>/edit is obvious, but contains a verb in the URL. Changing this parameter to GET /resource/<id>/editable solves this problem, but at an apparently superficial level. Is that all you need to do - change verbs to adjectives?

If instead I use POST to retrieve the editable version, then how can I distinguish between POST, which initially retrieves it, and POST, which saves it? My (weak) excuse for using POST would be that retrieving the editable version will result in a change in state on the server: blocking the resource. But this is only true if my requirements are to implement such a lock, which is not always the case. PUT does not work for the same reason, plus PUT is not enabled by default on the web servers I'm running on, so there are practical reasons not to use it (and DELETE).

Please note that even in the editable state I have not made any changes; presumably when I send the resource again to the web server, I would LET it. But in order to get what I can later than POST, the server must first serve a specific view.

I guess another approach is to have separate resources at the collection level: GET /read-only/resource/<id> and GET /editable/resource/<id> or GET /resource/read-only/<id> and GET /resource/editable/<id> ... but it looks pretty ugly to me.

Thoughts?

+4
source share
6 answers

1) It is perfectly true to have two different resources: one for viewing and one for editing some domain concept. Just keep in mind that since they are two different URIs in terms of REST, they are two different resources. Too often, people associate a resource with a domain object. That's why they end up getting stuck in CRUD only.

2) Do not suspend the resource name. The important thing is that you understand what the URI points to “thing”, “resource”. If this is more obvious to you with editable instead of edit , then use this. Having a verb in your URL does not make your application incorrect; it just makes it less clear to the human developer. Using the verb in the URL to try to redefine the semantics of the HTTP method is now a violation of the unified interface restriction.

+6
source

In REST, editing an existing resource is done by the client by the GET representation of the presentation of this resource, making changes to the presentation, and then performing the PUT of the new view back to the server.

So, to just read the resource, your REST client program would do:

 GET http://www.example.com/SomeResource 

And edit this resource:

 GET http://www.example.com/SomeResource ... edit it ... PUT http://www.example.com/SomeResource 

Usually, simultaneous updates are processed, allowing the last PUT arriving at the server to overwrite earlier ones, on the assumption that it is a newer state. But in your case, you want to protect yourself from this.

Take a close look at @Jason's suggestion to support an additional parallel blocking resource for each main resource. Your client will first create a lock, edit it, and then remove the lock. The system will need to automatically cancel the lock if the user making the lock subsequently never saves any changes. It will look like this:

 GET http://www.example.com/SomeResource ... user presses an edit button ... PUT http://www.example.com/SomeResource/lock ... user edits the resource representation ... PUT http://www.example.com/SomeResource DELETE http://www.example.com/SomeResource/lock 

You will need to do the appropriate error handling if the user is trying to edit a resource that is blocked by someone else.

It sounds like you feel limited by the current limitations of HTML. If you use a server-side REST framework such as Restlet (for Java), it supports the concept of “overloaded POST,” where you can use POST but adhere to the query string argument, for example method = PUT or method = DELETE. If you write your own server components, they can use this trick too.

There are tricks that you can play at the HTML level. For example, only a read-only part and an input form that is not initially shown may be displayed on your page. When the user clicks the edit button, your JavaScript hides the read-only part and shows the input form.

Be sure to read Richardson and Ruby Restful Web Services (O'Reilly). It is very useful.

+3
source

I don’t think that returning a form or just values ​​depends on the REST server, but also on the responsibility of the client. Whether a resource is editable is a property of the resource, not something specific to the URL.

In other words: URL to get the resource GET /resource/<id> . This property is editable. If the user wants to receive the form, he can receive the resource from the same URL and fill out the form. The client can change the PUT / POST.

+3
source

How to create a url to get a read-only or editable version?

The main problem here is that you create URLs in the first place - adding identifiers to hard-coded URLs is not REST. Roy Fielding wrote about this same mistake . Which document asks you to edit the resource must contain the URI for the editable version of this resource. You follow this URI, regardless of whether /resource/editable or /editable/resource is outside the REST scope.

+2
source

If instead I use POST to retrieve the editable version, then how can I distinguish between POST, which initially retrieves it, and POST, which saves it?

You do a GET (not POST) to read the resource and POST (or PUT) to write the resource.

If you want to create a lock for the resource in question, use POST to write to the resource (or the resource container with the resource identifier encoded in the POST body), and let the server create the lock as a new resource and return the identifier of this resource in response to POST. (with authentication questions beyond your question or answer)

Then, to unlock the lock, use DELETE in the lock resource or POST in the lock container.

+1
source

I assume your question might be "how to define a read view that returns with a GET action in a PUT action?". You can do it:

 <Root> <readonly> <p1><p1> ... <readonly> <others> ... <others> <Root> 

After parsing the XML request from PUT, you can ignore the readonly part and process the others. In response, return status 200 and leave a message stating that the part in readonly is ignored. Is this your expected?

0
source

Source: https://habr.com/ru/post/1335179/


All Articles