[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)