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