TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Who Cares about GET vs. POST? NoREST

55 点作者 swax大约 10 年前

24 条评论

mbleigh大约 10 年前
Except that RPC-structured APIs are complete garbage to consume for external developers because, surprise, they don&#x27;t know or care what your internal function names are. And if you aren&#x27;t thinking about the experience of real or theoretical third-party developers when building your API, why even have one at all?<p>If you ignore HTTP verbs and status codes you&#x27;re just making it harder for other developers to grok your system. It&#x27;s less about adherence to some strict standard and more about helpful signaling. A GET fetches data, POST creates new records, PUT is idempotent, DELETE deletes. 4xx status codes indicate a request error, 5xx indicate a server error. That&#x27;s all useful information for someone trying to integrate with your API, but you think that instead everyone should memorize your in-house conventions. Good luck getting buy-in on that.<p>The only partial agreement I&#x27;d give to this is that I no longer think it&#x27;s wise to nest multiple levels of resource IDs (e.g. &#x2F;customer&#x2F;123&#x2F;order&#x2F;456). This is, again, out of respect for external developers. Instead, I would have &#x2F;customers&#x2F;123 and &#x2F;orders&#x2F;456 (assuming that IDs can&#x27;t be duplicated between customers). A flatter URL structure (which is, note, still REST-friendly) can be an easier-to-consume experience for other devs.
评论 #9139172 未加载
评论 #9139622 未加载
评论 #9139967 未加载
nothrabannosir大约 10 年前
<i>&gt; Why not simplify by removing parameters from the URL altogether?</i><p>Caching. Put a caching proxy in front of your api endpoint and enjoy.<p>This is the same reason you&#x27;ll want to do:<p><pre><code> &#x2F;api&#x2F;customer&#x2F;1234&#x2F;order&#x2F;abcd </code></pre> instead of:<p><pre><code> &#x2F;api?customer=1234&amp;order=abcd </code></pre> Because even if your cache includes query strings (which it may, and you can configure it to), you lose order. Now you also have to configure your cache to ignore ordering on the query string, and that&#x27;s a lot less obvious (and probably not even HTTP compliant?).
评论 #9139949 未加载
评论 #9143994 未加载
lmorchard大约 10 年前
You have missed the point of REST. REST is an architectural pattern for a World Wide Web global-scale system. Your API may not fit that description. Thus, REST may not be appropriate for your API.<p>Following the REST patterns means you can take advantage of things like standard agnostic intermediaries for caching &amp; filtering. You can switch or even spread across service providers by changing domain names in URLs. You can mitigate network issues through guaranteed idempotence and using conditional headers like if-none-match. These are all issues that you&#x27;ll probably have to rediscover and re-solve on your own, if your API lives long enough.<p>It is not about SEO or visually &quot;clean&quot; URLs. REST says nothing about that, despite many misconceptions otherwise. In fact, in a truely RESTful service, resource URLs can be obscure garbage like <a href="http://example.com/A13D-DE45-32BC" rel="nofollow">http:&#x2F;&#x2F;example.com&#x2F;A13D-DE45-32BC</a>. If you&#x27;re using the HATEOS principle, those URLs will be picked up from links in your responses.<p>&quot;Pidgeonholing&quot; your errors to standard HTTP error codes means that you&#x27;ve followed a shared standard, rather than inventing your own from scratch. Also, 4xx errors generally refer to something in the client&#x27;s request, while 5xx errors generally mean something has gone wrong while generating a response on the server side.<p>If you don&#x27;t need any of these things - because, say, you&#x27;re building an API that will only be used between two parts of your own small system - then don&#x27;t worry about REST. Go ahead and build something along RPC lines.<p>You might regret it someday, if you find yourself needing the scaling characteristics of the WWW. But, many systems never grow to that point anyway.
stupidcar大约 10 年前
Pure REST is great for toy examples, where every domain entity fits neatly into a resource and every operation is a CRUD one that can be represented as an HTTP verb. So there is a million tutorials explaining how to build a REST API for a blog with BlogPost and Author resources, or an ordering system with Customer and Order resources.<p>However, when you move beyond these simple examples and start trying to build a REST API for a messy, complex system, you immediately run into trouble. How do you deal with non-CRUD operations? How do you deal with long running processes? Or entities in an indeterminate state? How do you aggregate multiple resources into individual request&#x2F;responses for performance? How do you de-duplicate identical entities within an aggregated response? How do you return only particular fields? How do you handle paging and filtering? How do you handle transactions? How do you handle authentication and security restrictions?<p>All of these things can be solved, but by the time you&#x27;ve finished, your API will be far from easy to understand. It will need a load of accompanying documentation to make it usable, and will have a bunch of weird corners where you&#x27;re initiating operations as a side effect of setting entity flags, or you&#x27;ve noun-ed verbs in order to turn an abstract operation into a resource. E.g. PUT &#x2F;server-reboot-attempt.
评论 #9140404 未加载
评论 #9140526 未加载
评论 #9141335 未加载
stilkov大约 10 年前
What an incredibly clueless post. I thought we’d left that level of misunderstanding behind us a few years ago.<p>There is no such thing as a RESTful URL. Characters in URLs don’t matter.<p>GET and POST have different semantics. Ignoring the benefits of caching is just dumb.<p>The semantics of status codes and verbs are defined pretty clearly. You might have to read an actual spec.<p>A paragraph starting with “A core difference between REST and RESTful …” physically hurts.<p>I can’t believe I just wasted time actually commenting on this.
beders大约 10 年前
If you are mapping your RPC-style API into a REST interface, you are doing it wrong.<p>REST as an architectural <i>style</i> wants you to think as your API as a collection of resource representations that can be manipulated through simple verbs (as the one present in HTTP).<p>It forces you to think about idem-potency, caching, namespacing, immutability and robustness.<p>If your API doesn&#x27;t have abstractions for long running processes or more complex business transactions, you don&#x27;t have a RESTful API and need to adapt it.<p>Furthermore, if payload size and minimizing the number of requests is your most important goal, why are you using HTTP in the first place? It&#x27;s not the right solution for you.
评论 #9139956 未加载
regularfry大约 10 年前
&gt; In other languages API calls don’t return with function pointers to related functions.<p>Let me introduce you to a little something called <i>objects</i>.
hughes大约 10 年前
Completely beside the point of the article, but just seeing a url like &quot;&#x2F;customer&#x2F;33245&#x2F;order&#x2F;8769&quot; makes me anxious that the author might give multiple customers the same order number.
评论 #9144695 未加载
评论 #9143924 未加载
xienze大约 10 年前
Congratulations, you&#x27;ve discovered RPC.
评论 #9139425 未加载
omgitstom大约 10 年前
It would have been nice if he proposed something innovative moving forward, but this is a step back to RPC-structured APIs. After reading this though, I had to check to make sure it wasn&#x27;t April 1st.
评论 #9139885 未加载
评论 #9139648 未加载
treve大约 10 年前
How the url is formatted is irrelevant for REST.
评论 #9139105 未加载
dragonwriter大约 10 年前
The criticism they start with is weird. They take this API call:<p><pre><code> OrderDTO Customer::GetOrder(int customerID, int orderID) </code></pre> And this HTTP call:<p><pre><code> GET &#x2F;customer&#x2F;33245&#x2F;order&#x2F;8769 </code></pre> And ask:<p>&gt; If we put the function name between the parameters themselves, then it leads to the question, what part of this URL is the endpoint?<p>But the thing that is between the parameters is &quot;order&quot; not the function name &quot;GetOrder&quot;. If you look at an alternative form in which one might (more idiomatically, in some languages) see the API call, the relation to the HTTP call is more clear:<p><pre><code> Customers[customer_id].Orders[order_id] # =&gt; Order </code></pre> &gt; REST URLs look ‘cleaner’, but are they easier to understand?<p>Yes.<p>They go on to say:<p>&gt; A simpler API, similar to our original function call would have no mixing of parameters with the name, and clear definitions of the parameters being passed in.<p>With this example:<p><pre><code> GET &#x2F;customer&#x2F;getOrder?customerID=33245&amp;orderID=8769 </code></pre> How is that simpler? Sure, depending on how you&#x27;ve implement the backend, it may be a more direct reflection of the backend code, but there is a difference between &quot;leaky abstraction&quot; and &quot;simpler&quot;. Also, why is the fact that the action is &quot;getting&quot; something reflected twice?<p>&gt; Why not simplify by removing parameters from the URL altogether? Put them in the query string, or post body as JSON.<p>Sure, RPC-over-POST is an alternative (older than REST) style of Web API, and if that&#x27;s what floats your boat, do it. OTOH, &quot;removing information from the URL for aesthetic reasons&quot; may not be the best reason to move a safe operation from GET, which is defined as safe, to POST, which is neither safe nor idempotent, particularly if you are using middleware that is aware of HTTP semantics -- you&#x27;ve just thrown away valuable information.<p>&gt; Your API can encounter many application specific exceptions while processing a request, but why try to pigeon hole your error response into a limited number of error codes designed for retrieving hypertext?<p>Why <i>not</i> choose the best error code of those available in the protocol? In a traditional programming language, would you just throw the most generic possible exception? Because that&#x27;s what the &quot;just use 200 for success and 500 for failure&quot; approach is equivalent to.<p>&gt; Verb agnostic, HTTP verbs are really only needed to identify where parameters will go – for GET it’s in the query string, For POST, in the body.<p>If you are going to use HTTP, why fight against it by throwing out its defined semantics? Aside from reducing the value you get from existing HTTP-semantics-aware software, you are just forcing yourself to reinvent the wheel.<p>&gt; REST is a style, not a standard.<p>Whether REST is a style or a standard is irrelevant when your post is advocating abandoning it completely in favor of RPC-over-HTTP with deliberate disregard for HTTP&#x27;s defined semantics.
评论 #9139059 未加载
评论 #9139785 未加载
评论 #9139081 未加载
评论 #9139111 未加载
aaronem大约 10 年前
Microsoft-stack developer doesn&#x27;t understand how HTTP works. Film at eleven.
评论 #9144017 未加载
BerislavLopac大约 10 年前
Wait, was this a serious post or some sort of The Onion-like satire?
jawb大约 10 年前
REST is good, better than RPC, SOAP... finally people can understand and use APIs easily and happily. The URL &#x2F;customer&#x2F;33245&#x2F;order&#x2F;8769 is perfect, looks like a directory path and reflect the relationship between the entities. Arguing about the best url, status code and best verb is the irrelevant part in REST. Why can&#x27;t people just do whatever it works for the users while respecting the standards when they can ?!
评论 #9139802 未加载
saurabhnanda大约 10 年前
I am increasingly getting irritated with REST for our app. It takes too much thought to figure out the &quot;correct RESTful approach&quot; when building out an API endpoint. And then again, there are no right answers. And all the JSON serialization&#x2F;de-serialization logic, for every single endpoint. Too. Much. Work.<p>I&#x27;m wondering why Thrift&#x2F;Proto-buffers aren&#x27;t popular? Even for browser-based JS clients. What&#x27;re the pitfalls?
评论 #9140516 未加载
kolarski大约 10 年前
Is it just me or GET &#x2F;customer&#x2F;33245&#x2F;order&#x2F;8769 is wrong You have unique order id... then use it GET &#x2F;order&#x2F;8769 like that ??
评论 #9144654 未加载
kid0m4n大约 10 年前
How about this then?<p>GET &#x2F;index.php?do=getOrder&amp;customerID=33245&amp;orderID=8769
rbelouin大约 10 年前
&quot;Does any language force you to prefix a function with 4 verbs?&quot;<p>Actually, I don&#x27;t really know. But for sure HTTP isn&#x27;t forcing you to only use GET&#x2F;POST&#x2F;PUT&#x2F;DELETE, even if this verbs are usually enough to design your API. It&#x27;s quite funny to hear some people (I&#x27;m not talking about the author) joking about the &quot;418 I&#x27;m a teapot&quot; response status, which is defined in a HTTP extension, and then telling you that having only 4 methods to design an API is too restrictive.<p>HTTP is extensible, so why misusing it?
rcari大约 10 年前
Well REST allows for resources to be accessed as they are: resources. Using POST&#x2F;GET query parameters implies that the server should do some actual processing on these to deliver the requested resource. With REST, you can have the resource be a static file on the server, no processing required.
评论 #9139053 未加载
rondon2大约 10 年前
Thank you! I was wondering why I couldn&#x27;t just use post for a function I&#x27;m writing right now. It helps to have someone else say out loud what I was thinking.
igorescobar大约 10 年前
Just another kid with a keyboard and High Speed Internet.
LoSboccacc大约 10 年前
The answer basically is caches and proxies.
giampierod大约 10 年前
Why you use GET vs POST are conventions. There are no way to enforce any rules in web services and conventions help to make the things you are looking at recognizable. And conventions do change over time. I think we need more HTTP verbs like START and STOP and I wish POST was NEW. Merge vs. update-all for PUT is still not well established and now we have PATCH. Such terrible names. I would love something like REPLACE and MERGE or something more descriptive.<p>I also think that your customer order example could have been done better. Something like<p>Your example: OrderDTO Customer::GetOrder(int customerID, int orderID) But that&#x27;s the wrong side of the equation, that&#x27;s the definition of the function. If you call the function it would look like this: GetOrder(myCustomerID, myOrderID)<p>And an equivalent REST call would look like this with a little clean up. GET &#x2F;orders&#x2F;?id={id}&amp;customer-id={customer-id}<p>Doesn&#x27;t look that much different to me. Sure you could have done GET &#x2F;orders&#x2F;{id}&#x2F;?customer-id={customer-id}, but there is no reason why the above is wrong from a RESTful perspective. Why would you marshall a whole JSON payload to do a simple GET? You are not creating a tuple to pass the two parameters in your full-language function example, what&#x27;s the reason it is required for the RESTful call?<p>As I mentioned above HTTP needs a couple more verbs and aliases for the existing verbs. You think of situations like:<p>START &#x2F;timers STOP &#x2F;trains<p>A lot of the time we jam POST and PUT in this situation and they are poor substitutes for a larger verb vocabulary. I have built a few automation projects and any actions you do can usually fit into<p>NEW GET UPDATE (merge) DELETE START STOP OPEN CLOSE<p>still limited, but pretty good at covering almost all the verbs needed. You supply the nouns.<p>NEW &#x2F;vms START &#x2F;vms OPEN &#x2F;remote-desktop&#x2F;1234 CLOSE &#x2F;files&#x2F;folder&#x2F;path&#x2F;to&#x2F;file<p>Especially with persistent connections in HTTP2 and web sockets and things of the kind OPEN and CLOSE will likely be need to establish these kinds of connections. You could probably get away with using START and STOP though, such as:<p>START &#x2F;remote-desktop&#x2F;?computer=1234<p>As for HTTP error codes. They need an overhaul. 404 and 403 do the job fine, but giving the user an idea of whether their JSON was malformed (Syntax) vs. the data in the payload was invalid is difficult to distinguish with just 400. But the return payload should describe the error in detail. Not many conventions there to help.<p>As for HATEOS, I used to think it was great, but I am meh on it now. It needs refinement.