7

With respect to REST and ASP.NET Web API, is it necessary to add the identifier to the route for a PUT action method even when the DTO payload (e.g., JSON) itself specifies the identifier?

For example:

public void Put(int id, [FromBody]SomeDto someDto) // someDto has an 'Id' property

The ASP.NET Web API template includes the id parameter and I have seen many examples of this.

In contrast, is it OK to omit the id parameter and still adhere to REST guidelines? For example:

public void Put([FromBody]SomeDto someDto)
DavidRR
  • 18,291
  • 25
  • 109
  • 191
kwiri
  • 1,399
  • 2
  • 15
  • 22
  • You can write, but then it should be a `POST` not the `PUT` – Divyang Desai Nov 15 '16 at 17:47
  • Is the id an internally generated key or a natural key? If you're using PUT to create a new item, how would you know what the id is? – Jasen Nov 15 '16 at 17:56
  • I think PUT is [Idempotence](https://en.wikipedia.org/wiki/Idempotence). and it's use to update. instead of create – Divyang Desai Nov 15 '16 at 18:01
  • 1
    I want to use the put method for updates. I am really trying to use what everybody is doing just to use whats popular convention and just make my api as what everybody does.The Id is part of the someDto this is something really simple nothing fancy just a dto with an id property – kwiri Nov 15 '16 at 18:14
  • @kwiri: simply you can use. – Divyang Desai Nov 15 '16 at 18:25
  • 1
    See [Put vs Post](http://stackoverflow.com/questions/630453/put-vs-post-in-rest) with examples having id. – Jasen Nov 15 '16 at 18:36
  • There is no need to send an `id` twice. Keep it simple. – alex Nov 16 '16 at 08:39
  • @dit I agree too thanks – kwiri Nov 16 '16 at 16:34

1 Answers1

5

Consider the default ASP.NET Web API route template:

api/{controller}/{id}

...and a route that matches that template:

api/persons/42

Then, your first method signature:

public void Put(int id, [FromBody]SomeDto someDto)

...will ensure that your DTO identifier (e.g., 42) appears in the URI for a PUT request as is considered good practice as described here and here.

Within your Put action method, you can then consider checking that the identifier specified in your DTO matches the identifier specified in your route. And if they differ, return the HTTP status code 400 Bad Request:

if (someDto.Id != id)
{
    return BadRequest("The DTO identifier does not match the identifier in the route.");
}
DavidRR
  • 18,291
  • 25
  • 109
  • 191