4 ms·
Forgive my lack of knowledge of ReST, but why is "/topic/add" a bad API endpoint, and why should verbs be avoided? How else would you get the "Add Topic" form?
by windsurfer 13y ago
Forgive my lack of knowledge of ReST, but why is "/topic/add" a bad API endpoint, and why should verbs be avoided? How else would you get the "Add Topic" form?
- bryanh 13y ago`/topic/add` would be a fine URL to return the form HTML, the "RESTful" API would be like `POST /api/topic` where POST implies create and topic implies, well, topic.
- lgas 13y agoOften the best approach is to have e.g. /topics be both the API endpoint and the web endpoint for the collection of topics resource and e.g. /topic/<identifier> be the endpoint for individual topic resources. In both cases the server loads the same data, but if the negotiated content type is text/html then it renders an HTML template with the data and returns a page showing a (probably paginated) topic list along with a form for posting a new topic (possibly hidden and revealed by javascript on a button click, etc). The form would POST to the /topics endpoint which would create the new topic and then return a redirect to the /topic/<identifier>. Another form might also allow replacing existing topics by PUTing to a /topic/<identifier> endpoint. Or via PATCH for use via AJAX. The actual /topic/<identifier> links in both the HTML and JSON views would really be something like /topic/<id> or /topic/<uuid> or /topic/<slug>. Again, if you click on one of the topic links in the HTML view in a browser then when you land on the individual topic link it will also negotiate the text/html content-type and you'll get the topic detail page, etc. If you have pages like "most recent topics" or "trending topics" etc they could be mapped to separate collection resources like /topics/recent, /topics/trending, etc that are just projections of the appropriate subset of the overall collection resource. If the negotiated content-type of any GET request is application/json (or e.g. application/edn) then it returns the API results in the appropriate format. If you follow one of the same links served from the JSON file from your API client, then it will again negotiate application/json and it will get the JSON version the topic detail. The JSON results might be in a format like http://stateless.co/hal_specification.html http://stateless.co/hal_specification.html.
- falicon 13y agoIn the PDF he points out it says "Resource names should be nouns—avoid verbs as resource names. It makes things more clear. Use the HTTP methods to specify the verb portion of the request." However the same PDF, in the very same section, states "Having sensible resource names or paths (e.g., /posts/23 instead of /api?type=posts&id=23) improves the clarity of what a given request does." To me - having the verb in the resource name is very sensible specifically because it improves the clarity of what a given request does (or at least is intended to do). And as a personal style thing, I usually put the verb first (it reads more like English that way) so I would have gone /add/topic -- but again that's just a personal style/organization thing.
- aaronem 13y agoThe whole idea behind REST resources, though, is that the HTTP method expresses the action, and the URI identifies the object acted upon. In that conceptual scheme, there is neither need nor place for verbs in the URI; POST /topics/add is redundant, because POSTing to a collection already has the semantic value of "add an item to this collection". Similarly, if you're modifying an existing item, you don't need to PUT /topics/23/edit or what-have-you; PUT already means "replace the existing content with the request body I'm sending", so all else that's required is to identify the particular content to replace, for which /topics/23 suffices. Having the HTTP method and the endpoint gives you all the clarity you need in terms of what a request does, and to which thing it does it. An additional, and very non-trivial, benefit of this scheme is that it is standard and discoverable: "standard", in the sense that these basic HTTP operations are defined in RFC 2616 and exhaustively documented there; "discoverable", in the sense that knowing some endpoint represents a REST resource API instantly tells you quite a lot about how you can interact with it, and you can find out the rest from the responses you get when you make API requests -- which responses RFC 2616 also explains how to interpret. Not everything is simple. REST resources are, and they need not have a complex API. Poorly thought-out APIs for simple things require a lot of documentation, that mostly being lousy explanations of the interactions between an incomplete set of edge and corner cases. Well thought-out APIs for simple things barely require any documentation at all. The REST resource API is a sterling example of the latter sort; once you're familiar with RFC 2616, you can discover everything else you need from the responses you get to API requests. This is not so when redundant verbs -- POST /topics/add -- are used in a backwards namespace -- POST /add/topic -- with uncertain naming -- /add/topic, so if I want all topics do I GET /topics or /topic, or /get/topics, or what? What makes all this confusion more worthwhile than just using REST resource endpoints? Do you want people who consume your API to curse your name for making them deal with a bunch of needless impedance matching, or to effortlessly retrieve what you're offering and do something amazing with it?