Maciej Kizlich
Maciej Kizlich

Reputation: 123

Two identical REST mappings with different HTTP request types

Let's assume we have two methods on the REST controller:

@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
@ResponseBody
public UserDTO showUserDetails(@PathVariable("userId") Long userId) {
/* code here */
}

@ResponseStatus(HttpStatus.ACCEPTED)
@RequestMapping(value = "/{userId}", method = RequestMethod.POST)
@ResponseBody
public UserDTO editUser(@PathVariable("userId") Long userId, UserDTO userToEdit) {
    /* code here */
}

So we have two identical URIs mappings, but supporting different HTTP requests. My question is: is this approach acceptable in terms of designing APIs? Or it is better to map second method to something like /{userId}/edit ?

Also, when using hateoas paradigm, the response will look somewhat strange:

"links":[{"rel":"self","href":"http://1localhost:8080/root/users/1"},{"rel":"edit","href":"http://localhost7:8080/root/users/1"}]

With 2 different URIs looking identical.

Upvotes: 1

Views: 320

Answers (3)

inf3rno
inf3rno

Reputation: 26137

From a REST perspective what matters that you use the proper HTTP method and a single resource identifier (URL) is mapped only to a single resource. The URL structure does not matter. It matters only for you by routing the requests.

Your choice of method is bad. By edit you have to use PUT (full) or PATCH (partial) instead of POST. If you cannot use these methods because of some purposes (for example you use plain HTML forms to send requests), then you should use method override. For example send the real method in a _method param, in the body, in the query, or in a header. (It does not really matter which you choose because it is already an ugly workaround. Most ppl prefer the query.)

By choosing the URL most ppl prefer to use only nouns. This is because you don't map URLs to operations (like SOAP RPC), which are verbs (and probably nouns). For example POST /GetCurrentPrice. You map URLs to web resources, which are nouns for example GET /currentPrice.

REST is pretty simple. It uses existing standards to describe an uniform interface. Sadly most web developers do not know the HTTP standard. You should read at least the HTTP method definitions, the HTTP status code definitions and the URI RFC. These are the basics by REST.

Upvotes: 1

Ricardo Veguilla
Ricardo Veguilla

Reputation: 3155

In terms of REST API design, you mapping is correct. For a given resource, you should interact with it via a single URI, In you example:

http://localhost:8080/root/users/1

And specify the operation via HTTP verbs.

Check the RESTful API HTTP methods in REST - Applied to web services, for an example.

Upvotes: 2

Linora
Linora

Reputation: 10988

I would definitely change the request mappings. For your editUser I'd add a /edit/ so your URL would look like http://localhost7:8080/root/users/edit/1

For the show you could add a /view/ to the URL, but that's not really necessary, but for the edit I'd personally prefer to have the URL be selfexplanatory

Upvotes: 1

Related Questions