[HN Gopher] An Introduction to APIs ___________________________________________________________________ An Introduction to APIs Author : teleforce Score : 138 points Date : 2023-07-30 15:54 UTC (7 hours ago) (HTM) web link (zapier.com) (TXT) w3m dump (zapier.com) | seveibar wrote: | This article advocates for a traditional REST API design. At | Seam, we use an API design that is like a RESTful RPC API, | inspired by the API at Slack. I think that HTTP RPC and Slack- | like APIs are much better than traditional REST because most | consumers of an API use an SDK, and RPC-style HTTP APIs optimize | for the SDK usage. | | We also built a framework like trpc but for Next REST APIs[1] to | get all the nice benefits of shared types but also the nice | benefits of OpenAPI generation that typically come with RESTful | frameworks https://github.com/seamapi/nextlove | synergy20 wrote: | maybe call it 'cloud APIs' | | It was written in 2014, not sure if it's still 'up to date' but | the articles seem well written, concise, to the point. | shortrounddev2 wrote: | I still like REST. Most web applications are CRUD and don't need | RPC. It also provides a standard and expected interface for 3rd | party developers integrating with your code. If you're a small | saas startup, nobody is going to waste their time learning the | particularities of your protocol. Also makes the code very easy | to read if you follow best practices for MVC style webapis with | dependency injection. In my view, asp.net core is the apex of all | RESTful frameworks | aridiculous wrote: | There's nothing like good technical writing. | ninja-ninja wrote: | was talking to someone about how product managers should have an | understanding of engineering and they said you should just know | what apis are haha | gumby wrote: | Title should say "Web APIs". | defanor wrote: | As should the contents. | dinoreic wrote: | REST is for noobs, JSON RPC is silent pro's choice :) | | Make all requests POST and enjoy easy life without useless | debates on should creation of resource be on POST or PUT or | should you return HTTP status 404 or 200 if resource/document on | server is not found (of course if should be 200 because request | was a success, 404 should only be used it api method is not | found). | | I 100% agree with Troy Griffitts beautiful take | https://vmrcre.org/web/scribe/home/-/blogs/why-rest-sucks | lprd wrote: | I've been a REST API developer for a few years now. For | whatever reason, I've never bothered dipping my toes in the RPC | realm. This article resonated with me. Looks like I'll be | building an RPC API in the near future. | atsjie wrote: | JSON RPC: | | - Everything is a POST, so normal HTTP caching is out of the | question. | | - JSON RPC code generators are non-existent or badly maintained | depending on the language. Same with doc generators. | | - Batching is redundant with HTTP2, just complicates things. | | - Because everything is a POST normal logging isn't effective | (i.e. see the url in logs, easy to filter etc). You'll have to | write something yourself. | | - Not binary like Protobufs or similar | | But yeah, "the silent pro's choice"... Let's keep it silent. | | JSON RPC is pretty much dead at this point and superseded by | better alternatives if you're designing an RPC service. | klabb3 wrote: | > - JSON RPC code generators are non-existent or badly | maintained depending on the language. | | Very much so. It's in a terrible state where I've looked. | Most of the tooling is by OpenAPI or similar which comes with | a bloatload of crap that is only marginally better than say | SOAP. It needs to be much simpler. | | > - Not binary like Protobufs or similar | | Agreed. This is not an issue for small things that can be | base64 encoded but once you need large blob transfers you | don't have any reasonable option. This is a problem in eg | graphql which also misses the mark and you have to step | outside for things like file uploads. | | It feels like the whole standardization effort around json | rpc is weak. It doesn't address the needs of modern RPC-like | systems. Which is unfortunate because there's a real | opportunity to improve upon the chaos of REST. | tornato7 wrote: | It's not ideal, but in practice GZIP base64 is only | marginally larger than GZIP binary | MuffinFlavored wrote: | i always fail to understand what kind of services there are | that _aren't_ at least RPC-ish | | thin CRUD wrappers obviously but usually when you are piping | data from one source/format to another, you typically want to | do something that is ever so slightly "not-CRUD" (call | another API/service, etc.) | parentheses wrote: | REST conventions only make sense for externally consumed APIs. | Even for those, there's GraphQL. | lenkite wrote: | Ahh, the 2000's called. They want their SOAP back. | dinoreic wrote: | Thank you all for the great comments. | | I want to emphasize that I was not thinking about JSON RPC as a | specific protocol, but more as a JSON format to transfer data, | similar to how REST APIs usually do, and some kind of "HTTP | method agnostic remote procedure call", it does not have to be | JSON RPC standard. | | Personally, I am a fan of just having API Class-es + methods | that automatically map to API calls with automatic api | interface and doc builders. I find that it would be super | strange if I had to prefix my internal methods with DELETE or | PUT based on do they remove or add to some Array. Using that | logic, why do that in APIs. | | I just find it super strange that people want to mirror their | app logic + error response codes to some protocol like HTTP - | ridiculous :) Why not go even lower as TCP and use some of that | spec for our client <> server API conn. Many people will laugh, | but if you think about it, where is the difference? | abraae wrote: | > I find that it would be super strange if I had to prefix my | internal methods with DELETE or PUT based on do they remove | or add to some Array. Using that logic, why do that in APIs. | | It's true that POST ends up being a bit of a grab bag for all | the non-CRUD API calls. | | But I find it very useful when looking over someonje's API to | find them using PUT, or DELETE. PUT in particular provides | really useful signals about the nature of the resource we are | dealing with. | | And lets not get started with the in-built caching etc. you | throw away by not using GET. | [deleted] | cle wrote: | I don't like REST either, but JSON RPC is similarly hamstrung | in some scenarios (examples: streaming, CDN caching, binary | encoding). | | I mostly dislike REST because nobody can agree on what it is | and there are too many zealots who love to bikeshed. If you | stick with the simple parts of REST and ignore the zealots, | it's decent enough for many scenarios. | | I've yet to find an RPC protocol that fills all requirements | I've encountered, they all have tradeoffs and at this point | you're better off learning the tradeoffs and how to deal with | them (REST, JSON RPC, gRPC, WebSockets, etc.) and how they | interact with their transports (HTTP/1.1, H2, QUIC, etc.), and | then play the unfortunate game of balancing tradeoffs. | kiitos wrote: | This article defines REST incorrectly, and doesn't seem to | understand the concept of HTTP methods, calling them verbs | (arguably fine) and types (huh?) seemingly arbitrarily. Methods | are a core part of HTTP -- just because you can't specify them | explicitly in a browser as a user doesn't mean they're "cryptic | curl arguments" or worth ignoring. I'm not sure I'd put too | much stock into this perspective. | eikenberry wrote: | +1 and I'll bump it up a notch... not only should you ignore | REST you should ignore URLs. You want to write protocols, not | APIs. Redis, for example, has a better "API" than any web API | I've used. Easy to use, easy to wrap, easy to extend and | version. HTTP is the other obvious example that I shouldn't | have to go into. | | If you'd like a good back and forth on the idea the classic c2 | page is a great resource. http://wiki.c2.com/?ApiVsProtocol | nine_k wrote: | Don't ignore URLs completely! They are great for namespacing | and versioning. | eikenberry wrote: | Why add the additional complexity of multiple connection | points? Protocols support both of those operations | perfectly well and it seems that adding URLs would just | confuse things. | nine_k wrote: | ReST makes sense in _certain_ cases, where resources are a tree | (like a typical web site is a tree), with collections of | leaves, and these leaves make sense by themselves. Then you can | go full HATEOAS and reap some actual benefits from that. | | Most of the time (like 99.9%) what you happen to need is JSON | RPC. Even if some parts of your API surface look like they | would fit the ReST model, the bulk does not. Ignore that, build | a protocol along the lines of your subject area. Always return | 200 if your server did not fail or reject the request, use | internal status signaling for details. Limit yourself to GET | and POST. Use HTTP as a mere transport. | ChrisArchitect wrote: | (2014) | danjc wrote: | Side point - has anyone got a better way to refer to a non- | technical person than "non-technical"? I see they use that term | in the intro and I use it to but seems a bit condescending. | FractalHQ wrote: | Muggle | [deleted] | pranavpiyush wrote: | Business user | macintux wrote: | I'm fine with that, but seeing the term "normies" here sets my | teeth on edge. | mellosouls wrote: | Layperson (layman in old money), though I don't think non- | technical is normally condescending. | | https://dictionary.cambridge.org/dictionary/english/layperso... | | _someone who is not an expert in or does not have a detailed | knowledge of a particular subject_ | | "bluffer" would be a humorous alternative. | gabereiser wrote: | The phrase you seek is called "Layman's Terms" as defined: | https://www.merriam-webster.com/dictionary/layman%27s%20term... | | This avoids classification of the reader. To refer to someone | who lacks the knowledge of a domain, they are a "layman". | gibb0n wrote: | noob | ch1234 wrote: | .... And that's the entire world is in this state. Stop trying | to create victims out of people for no reason. | | Non-technical = not technical = does not have technical | expertise. | | Seems pretty logical to me | vorpalhex wrote: | When an accurate term seems condescending, sometimes that tells | us more about ourselves than the word. | [deleted] | distantsounds wrote: | (2014) | delta_p_delta_x wrote: | Web dev has so thoroughly revised the definition of 'API' it's | not even funny. | | Desktop, embedded, video games, HPC suddenly cried out in terror | and were suddenly silenced. | rewmie wrote: | > Web dev has so thoroughly revised the definition of 'API' | it's not even funny. | | What leads you to believe that a HTTP API does not meet the | definition of a API? | debugnik wrote: | The other way around, the meaning of API standalone has been | narrowed to mean HTTP APIs, as if it were redundant. | Specially tedious if you're searching for non-HTTP API design | notes. | rewmie wrote: | > The other way around, the meaning of API standalone has | been narrowed to mean HTTP APIs (...) | | I don't think so. The pervasiveness of web apps and | applications consuming web services means there's a lot of | work involving web APIs. This doesn't mean the definition | of API was narrowed. It's all about context. If your bread | and butter is developing web services, you don't waste time | with context-free definitions of your API. You talk about | the API and everyone is on the same page. | evandale wrote: | If all anyone ever talks about is APIs in the web | services sense then, yes, the definition of API has been | narrowed. When everyone will assume you mean web services | API when you refer to an API and have to use extra words | to describe non-web APIs then the definition has | narrowed. That's how English works: the definitions of | words depend on their usage and dictionaries describe how | words are used. | | You even admitted "The pervasiveness of web apps and | applications consuming web services means there's a lot | of work involving web APIs" and "If your bread and butter | is developing web services, you don't waste time with | context-free definitions of your API" which is | acknowledging the common use definition of API has | morphed into Web API. It's only in the context of | technical documents or documents that are explicitly | referring to non-web APIs that use API and it is | understood to mean something other than a web API. | 3cats-in-a-coat wrote: | It's become just a word that means "interface endpoints". And | frankly that's fine, it's what it is in the end. Whether in an | OS, a website, or another platform. | lazyasciiart wrote: | One place I worked was unable to differentiate between | libraries, SDKs and APIs - they just called all of them "an | API". Infuriating. | capableweb wrote: | Well, to be fair, libraries and SDKs do have APIs, it's what | you mainly interact with when you use them, the defined | interface that you programmatically use in your application. | pdntspa wrote: | It is even weirder to me how business has latched on to the | term "APIs" like some kind of rabid dog biting into your ass | | Like, this is a fundamental aspect of how I interact with my | job and business has taken the term and elevated it into its | own distinct thing | booleandilemma wrote: | I died a little inside the day a new hire, some kid fresh out | of who knows where, shook my hand and asked "so are you an | API developer?" | foundart wrote: | Very well written. However, I have never thought of the word | 'endpoint' as used in API documentation in the way they describe | it. I have no idea what the true origin is but I've always | thought of it as the end of the journey the api request makes | over the network. | | > These are called endpoints simply because they go at the end of | the URL, as in http://example.com/<endpoint_goes_here>. | [deleted] | sibit wrote: | > POST - Asks the server to create a new resource | | > PUT - Asks the server to edit/update an existing resource | | Maybe I've been doing it wrong all these years but it seems to me | that the guides flip-flops the responsibility of POST and PUT. My | understanding is that POST should edit/modify while PUT | creates/replaces a resource. | hairofadog wrote: | I've always known it as stated in the article, and I'm pretty | sure that's right, though I've never noticed any functional | difference between the two (aside from what any given API may | enforce). | nighthawk454 wrote: | I thought the same, but apparently the article is correct | | https://www.ietf.org/rfc/rfc2616.txt | sibit wrote: | Interesting. I guess I've been going off of RFC 7231 | | > The PUT method requests that the state of the target | resource be created or replaced with the state defined by the | representation enclosed in the request message payload. | | https://www.ietf.org/rfc/rfc7231.txt | blowski wrote: | My rule of thumb: if you know the ID of the resource you're | creating, it's a PUT. If the system generates the ID, then | it's a POST. | treve wrote: | More generally the URI instead of the ID. | brosciencecode wrote: | Are you mistaking POST for PATCH? What I've been working with | is: | | - POST creates | | - PUT replaces (i.e. edit, but you need to provide the whole | resource) | | - PATCH edits (i.e. you can only provide some fields) | | APIs rarely implement all these properly in practice but that's | my understanding of the theory. | richardwhiuk wrote: | PUT can create - depending on whether the resource name is | client or server determined. | wak90 wrote: | I remember getting an interview question wrong when I said | "yeah a get is supposed to just respond with data but you're | writing it, you can make it do whatever you want" | charrondev wrote: | I mean most GET requests have at least one side effect: one | or more cache writes. | | I've also implemented some GET endpoints that are a GET but | have a side effect of marking something as read. (Normally | as a variant to an existing endpoint for sessioned user). | | I would expect at a minimum though if you are doing writes | during a GET it should be idempotent. | kiitos wrote: | Well, caching a response to a GET request is always going | to be subject to variables like Etag and other hashes of | the request, time limits, etc. which all ensure that | responses, even old responses, are never _wrong_, they're | at worst _stale_. | | That's different, and safer, than something like a "read" | bit on an entity, presumably tracked in an application | data layer. I don't think you can mark something as | "read" in your application from a GET request. Even if | your server sees the response to that GET request as | successful, it doesn't necessarily mean that the | requesting client actually successfully received the | response. As one of infinitely many possible counter- | examples, consider a middlebox between a client and your | server, where one client request to the server may | generate N requests from the middlebox to the server. | charrondev wrote: | While you might technically correct about using a GET to | mark a "read" bit as correct on some activity, in reality | there's a trade off to doing it in a PUT. | | Let's say you have some notification resource which is a | link redirecting to the thing that triggered the | notification. Ideally the notification will automatically | be marked read after the user sees the thing they | clicked. | | My setting the read bit in the GET that makes the | redirect you open up. 2 negative possibilities: | | - if someone could guess the GUIDs of the notifications | they could CSRF a users notifications as marked read. | (Unlikely and low impact if it does occur). - Adds the | potential that the client may not have loaded page after | the redirect and seen the resource. | | There is a UX tradeoff now though if we make this a | separate PUT after the page loads: | | - in a web application context the user will have to | either enable JavaScript so the app can automatically | mark this as read or have a separate form on every | landing page to mark it as read. | | Another alternative would be to make this a POST form to | view the notification that redirects but you have in | effect the same issue of the user maybe not loading the | page after the redirect. | | At the end of the day for something as minor as a | notification being marked read (as a result of a user | clicking directly on it), some idempotent modification | can work out and be easy to implement. | | Now to be clear I am referring to a purpose built | endpoint for a web application. | | We expose 1000s of truly restful endpoints that are used | outside of a web context and something like this doesn't | really make sense for them. | kiitos wrote: | You probably wouldn't use a PUT for anything like this, | true. But if you're going to mark a message as "seen" in | a way that would impact a UI widget like an "unread | notifications" red dot, then you almost certainly want to | make sure that the state-changing request for that | message is a POST, not a GET. | | There are just so many ways for GET requests to be | delivered to a server (or load balancer, or IP, or | domain, or...) multiple times for a given client request. | That capability is built in to HTTP and exploited in more | places than you can ever hope to account for, or even | detect. | eddd-ddde wrote: | During any serious side effects with a GET is a bad idea | because of xsrf anyways | puika wrote: | This is indeed the standard, AFAIK. Not sure what resources | mention otherwise but it seems like a lot, judging by the | comments around | samwillis wrote: | Somewhat agreed, I see them as: | | PUT - is effectively an "upsert" at a _specific url_. Doesn 't | exist? Create it, does exist? replace it. | | PATCH - update a resource with a diff, at a specific url. | | POST - _this is a RPC_ , in the case of a REST API it can be | used to create a new resource where the _" id"_ is not provided | and set by the server, it then redirects to the new url. | | POST can be used for any RPC endpoints, even as part of a REST | api. | capableweb wrote: | > My understanding is that POST should edit/modify while PUT | creates/replaces a resource | | The way I've been segmented them is based on idempotency. | | If you repeat the same call multiple times, do you get the same | result as if you just ran it once? Then PUT is appropriate. | | But if you have side-effects like creating new resources, that | would result in different action each time you make the call, | then POST it is. | | Idempotent methods include GET, HEAD, PUT and DELETE, the | resource should always end up in the same state after calling | them N times (barring errors/exceptions and such of course). | I'm fairly I got this from when I initially read the | specification, it's probably mentioned with a bit more grace in | the HTTP/1.1 spec. | jstx1 wrote: | And also what if you have a huge nested query which is only | reading the database but is difficult to pack into URL | parmeters (too long for example and you hit a character limit)? | POST with a json body instead of GET even though it's against | RESTful principles? ___________________________________________________________________ (page generated 2023-07-30 23:00 UTC)