0

I'm designing a REST API which has a Banner resource that's related to another two resources: Placeholder and Page.

While the relationship with Placeholder can be null, a Banner must be related to a Page. The business rules define that Pages are always created independently. Then, for new Banner resources, the page does always exist and the page's id can be passed as a parameter. The same applies for the Placeholder, although this could null.

So, I decided that a Banner resource can be also created independently (instead of a nested resource) as follows:

POST https://api.example.com/banners
{
  "name": "banner's name",
  "page": "PAGE_ID",
  "placeholder": "PLACEHOLDER_ID",

  ... other parameters
}

What error code should be returned by the API when provided page or placeholder does not exist?

I'm returning a HTTP 404, but it feels odd. I thought about 409, but this doesn't look like a conflict.

PD: If I used a nested URL as POST /pages/<page_id>/banners, the 404 makes sense for a non existent page, but it still have the same problem for placeholder.

Jose S
  • 620
  • 3
  • 8
  • 22
  • @CássioMazzochiMolin This may be considered as duplicate when passing the parameters in form of the post request body but not when using `POST /pages/page_id/banners`. And whether you use the one or other depends how you want to access the resources. So this is not an exact duplicate. – andih Apr 13 '17 at 14:39
  • @andih I read the question one more time and I still see it as a duplicate. The OP is concerned about the IDs sent in the request body. For the ones sent in the URL, a `404` will do the job as the OP mentioned in question. – cassiomolin Apr 13 '17 at 14:46
  • @CássioMazzochiMolin only as long as you take first idea of the banners resource as fixed / given. The author seems to be unsure whether this is the correct form because he proposed a second way. For the second approach he does not really know how to deal with the placeholder. One could also explain why to use the one or other approach and how to add the placeholder to the second one, .... – andih Apr 13 '17 at 14:55
  • @andih from @CássioMazzochiMolin's answer in the other post, I conclude that when using `POST /pages//banners`, if the `page_id` doesn't exist, a 404 would be returned, whereas, if the page's is ok, but `placeholder` doesn't, a 422 would be returned. Do you have an alternative solution? – Jose S Apr 13 '17 at 15:00
  • I'm reopening the question, but it should be the way to go. What stops you from following this approach? – cassiomolin Apr 13 '17 at 15:19
  • nothing, I like it. Just wondering if @andih had an alternative solution. – Jose S Apr 13 '17 at 15:42

1 Answers1

0

Assuming that you want to create a banner resource using POST /banners and that banner resource has

  • a required page attribute which value must be an existing PAGE_ID
  • an optional placeholder attribute which value must be an existing PLACEHOLDER_ID
  • and a name and other properties which I assume must also be controlled

Returning a 404 on post /banners is not a good idea

The consumer may provide from none to all invalid properties. Following your idea that would give something like that:

  • If only page is invalid you would return a 404
  • If only placeholder is invalid you would return a 404
  • If page and placeholder are both invalid you would have to return a 404 indicating that both value are invalid
  • If other properties are invalid, you would probably return a 400 Bad Request.
  • If page and/or placeholder and some other properties are invalid, which status return? a 404 or 400?

It's a bit complex and inconsistent and therefore not really usable for the API's consumer.

A 400 Bad Request is a better solution for post /banners

The best way to handle this use case is to consider all possible errors in the provided resources as a basic Client Error and therefore use 400 Bad Request status. The body of the response will contain a description of each error for each invalid property.

But there's a cleaner solution with POST /pages/page_id/placeholders/placeholder_id/banners

The POST /pages/<page_id>/banners is almost a good idea, you only need to push it further.

It seems that a banner goes into a placeholder which is in a page. If it's true you can do a POST /pages/<page_id>/placeholders/<placeholder_id>/banners to create a banner.

  • If page_id is invalid you return a 404 (indicating 'page not found')
  • If page_id is valid but placeholder_id is invalid you return a 404 (indicating 'place holder not found')
  • If page_id and placeholder_id are valid but property in the banner is invalid you return a 400 Bad Request (indicating which values are invalid)
Arnaud Lauret
  • 4,961
  • 1
  • 22
  • 28