Let's say I have a JavaScript web application which entirely uses a RESTful API for data.
Let's say this application has a data form, and let's say I'm editing a record at /product/12345. When building the form, I make a RESTful request to /product/12345 and get JSON data:
{
"id": 12345,
"name": "Some Product",
"active": true,
"sales_user_id": 27
}
So, my form obviously may have a dropdown list for selecting a sales person. I need to populate this list. Where should the data come from? What's the most common approach?
Would it make sense to make it part of the /product/12345 request response?
{
"id": 12345,
"name": "Some Product",
"active": true,
"sales_user_id": 27,
"sales_users": [
{"id": 1, "name": "Anna Graham"},
{"id": 2, "name": "Dick Mussell"},
{"id": 3, "name": "Ford Parker"},
{"id": 4, "name": "Ferris Wheeler"},
{"id": 5, "name": "Jo King"}
]
}
What about when creating a new record? Should my API also respond to GET /product/new, with the following?
{
"sales_users": [
{"id": 1, "name": "Anna Graham"},
{"id": 2, "name": "Dick Mussell"},
{"id": 3, "name": "Ford Parker"},
{"id": 4, "name": "Ferris Wheeler"},
{"id": 5, "name": "Jo King"}
],
"categories": [
{"id": 1, "name": "Category 1"},
{"id": 2, "name": "Category 2"},
{"id": 3, "name": "Category 3"},
{"id": 4, "name": "Category 4"},
{"id": 5, "name": "Category 5"}
],
"etc": [ ... ]
}
-
please never use GET request to create something. Your endpoint should be /product not /product/new. To create a new product you should send a PUT request to that endpoint.Kerem Baydoğan– Kerem Baydoğan2016年05月24日 07:51:08 +00:00Commented May 24, 2016 at 7:51
-
This is not creating anything. This is purely a request for existing data or a template for a new, not yet saved record.Chad Johnson– Chad Johnson2016年05月24日 10:07:58 +00:00Commented May 24, 2016 at 10:07
-
oh sorry, now i see what you mean. either way product endpoint should not be responsible for providing a template product or list-of-values for product-creation form drop-downs. as @Dan says just create separate endpoints and use caching headers so your browser can cache drop-down values for performance.Kerem Baydoğan– Kerem Baydoğan2017年01月18日 16:47:17 +00:00Commented Jan 18, 2017 at 16:47
2 Answers 2
I lean towards very simple, narrowly-focused endpoints. I would expect a request at some location like /sales_users which returns all sales users.
GET /sales_users:
[
{"id": 1, "name": "Anna Graham"},
{"id": 2, "name": "Dick Mussell"},
{"id": 3, "name": "Ford Parker"},
{"id": 4, "name": "Ferris Wheeler"},
{"id": 5, "name": "Jo King"}
]
Similarly, if you are going to have a list of categories, I would add a separate endpoint for that.
GET /categories:
[
{"id": 1, "name": "Category 1"},
{"id": 2, "name": "Category 2"},
{"id": 3, "name": "Category 3"},
{"id": 4, "name": "Category 4"},
{"id": 5, "name": "Category 5"}
]
I would not build a GET /product/new. Rather, I would build a form in your app to handle adding new products which knows the appropriate requests to populate its lists (e.g., GET /categories, GET /sales_users, etc.).
Assuming that the list of salespeople is relatively static, I would think you'd want a separate API call /salesusers
that you could call once (on form load, etc.) and save off so you don't have to re-request this data each time. Remember in REST, you are organizing your API around resources, and salespeople are logically separate resources from products.
Likewise, when calling /product/new
, you would only want to be submitting data for a new product, which might include a sales_user id, but nothing more. Changes to a sales_user itself would be a separate call.