Share
Embed
API Approaches: An Overview
A brief look at the most popular approaches for APIs
Stefan Tilkov
June 16, 2021
Transcript
45 slides
-
API Approaches: An Overview Te c h n o l
o g y L u n c h / O n l i n e / 2 0 2 1 - 0 6 - 1 5 STEFAN TILKOV @STILKOV -
Disclaimer This talk features •gross oversimpli f ications, •ludicrous exaggerations,
•personal takes, •questionable analogies and •a thorough lack of attention to detail but we only have 45 minutes. ! -
Overview of API styles •(g)RPC •HTTP Web APIs •Hypermedia REST
APIs •GraphQL •0-API -
Best of four decades of remote procedure calls on one
slide DCE/RPC Sun RPC CORBA MSRPC RMI Hessian Burlap .NET Remoting DCOM APPC Thrift SOAP XML-RPC JSON-RPC Ice -
Remote Procedure Call (in general) Interface Description Logical Communication IDL
Compiler Client Server Lib Physical Communication Lib (De-)Serialization Skel Stub (De-)Serialization -
General RPC issues •Tight coupling between client and server •Dangerous
location transparency illusion •Need for re-deployment synchronization •Incompatibilities after version changes •Unsuited for unknown/unexpected clients -
gRPC characteristics •Coupling between client and server via contract •Based
on Google Protocol Buffers data format and HTTP/2 •Widely used within Google and in many projects (e.g. Kubernetes) •.proto f iles de f ine services, requests, responses •Field indexes support (limited) compatibility between different versions •Support for streaming -
Bene f its gRPC Use for ef f icient, tightly
coupled, internal communication within distributed apps •High performance and throughput •Ef f icient resource usage •Mature implementation •Reasonable serialization •Static contract language -
gRPC Avoid for public APIs, unless you really need it
and are willing to ship SDKs Downsides •No generic semantics •Tight coupling •Limited compatibility •Static relationships •High demand on consumers •Static contract language -
URI Method Meaning http://ex.org/v1/customers POST create new customer http://ex.org/v1/customers/{id} GET
get customer details http://ex.org/v1/customers/{id}/orders GET get list of customer’s details ... ... ... -
HTTP API characteristics •Use of HTTP semantics •URI-focused •Strong focus
on server-side logic •Standard formats: JSON, XML, URI Templates, … •API description using OpenAPI/Swagger -
Bene f its HTTP APIs Use as default for simple
open APIs (but consider REST) •Ease of use •Generic semantics •Mature infrastructure •Tool support (esp. documentation) •Widely accepted •Low demand on consumers •No standard contract language -
URI Method Meaning http://ex.org/v1/customers POST create new customer http://ex.org/v1/customers/{id} GET
get customer details http://ex.org/v1/customers/{id}/orders GET get list of customer’s details ... ... ... Documented URIs become APIs Versions in URIs cause change for no good reason Assumptions about server details become facts -
HTTP APIs Avoid for public APIs you expect to maintain
for a longer time Downsides •Tight(er) coupling •Limited compatibility •Static relationships •No standard contract language -
REST characteristics •Basis for RESTful HTTP APIs: Using HTTP correctly
•Strong focus on server-side logic •Dynamic interaction based on hypermedia affordances: Links, link relationships, dynamic forms •Runtime discovery instead of development-time hard-coding •Evolvability via additional resources •Standard formats: JSON-LD, HAL, JSON-API, Siren, … -
How to turn an HTTP API into a REST API
in 3 easy steps -
<?xml version="1.0" encoding="UTF-8"?> <serviceDescription xml:base="http://om.example.com"> <link rel="all" href="/orders/" /> <link
rel="received" href="/orders/received/" /> <link rel="accepted" href="/orders/accepted/" /> <link rel="rejected" href="/orders/rejected/" /> <link rel="cancelled" href="/orders/cancelled/" /> <link rel="fulfilled" href="/orders/fulfilled/" /> <link rel="cancellations" href="/cancellations/" /> <link rel="reports" href="/reports/" /> </serviceDescription> <link rel="fulfilled" href="http://om.archive.com/orders/" /> { "serviceDescription" : { "base": "http://om.example.com", "links": [ { "rel": "all", "href": "/orders/" }, { "rel": "all", "href": "/orders/" }, { "rel": "received", "href": "/orders/received/" }, { "rel": "accepted", "href": "/orders/accepted/" }, { "rel": "rejected", "href": "/orders/rejected/" }, { "rel": "cancelled", "href": "/orders/cancelled/" }, { "rel": "fulfilled", "href": "/orders/fulfilled/" }, { "rel": "cancellations", "href": "/cancellations/" }, { "rel": "reports", "href": "/reports/" } ] } } -
{ "resources": { "http://example.org/rel/widgets": { "href": "/widgets/" }, "http://example.org/rel/widget": {
"href-template": "/widgets/{widget_id}", "href-vars": { "widget_id": "http://example.org/param/widget" }, "hints": { "allow": ["GET", "PUT", "DELETE", "PATCH"], "representations": ["application/json"], "accept-patch": ["application/json-patch"], "accept-post": ["application/xml"], "accept-ranges": ["bytes"] } } } } https://mnot.github.io/I-D/json-home/ -
GET /order/123 { "order": { "date": "2013-07-02", "total": 1240.02, "..."
: "...", "links" : [ {"rel" : "self", "href" : "http://example.com/orders/123"}, {"rel" : "contacts", "href" : "http://example.org/A3BEF1"}, ... ] } } -
GET /order/123 { "order": { "date": "2013-07-02", "total": 1240.02, "..."
: "...", "links" : { "self": "http://example.com/orders/123", "contacts": "http://example.org/A3BEF1", ... } } } Your future extensions -
{ "order": { "state" : "received", "..." : "...", "links"
: [ {"rel" : "cancel", "href" : "http://..."}, {"rel" : "accept", "href" : "http://..."}, {"rel" : "reject", "href" : "http://..."}, ... ] } } -
{ "rel": "search", "template": "http://example.com/search?q={query}" } <form action='http://example.com/search'
method='GET'> Search for: <input type='text' name='query'> <input type='submit'> </form > -
{"target": "http://example.com/add", "rel": "add", "template": { "first": "...", "last":
"...", "bdate": "..." } } <form action='http://example.com/add' method='POST'> First: <input type='text' name='first'> Last: <input type='text' name='last'> Birthday: <input type='date' name='bdate'> <input type='submit'> </form > -
Bene f its REST APIs Use for maximum evolvability and
long- term needs •Loosest possible coupling •Dynamic affordances •Evolvability for new needs •Server-side logic •Generic semantics •Mature infrastructure -
REST APIs Avoid for high-ef f iciency needs or in
case of strong resistance Downsides •Harder to use (it’s not easy to be simple) •Requires consumer cooperation to succeed •Continuous justi f ication required -
GraphQL •Query and mutation language for graphs, tunneled via HTTP
POST •(Recursive) selection of desired nodes and properties •Pagination •Subscriptions •Tool support for caching, of f line availability •Tooling for server-side bridging to existing APIs and databases •Native query syntax, JSON output -
Bene f its GraphQL Use for accessing graph- based data
in unforeseen ways •Ease of use (?) •Standardized query semantics •Data selection •Extensive tooling •Subscription support -
GraphQL Avoid for server-centric logic, beware of SQL-on- steroids effect
Downsides •Client-side logic •Tight coupling via data relationships •High server-side complexity •Risk of “Lipstick on a pig” effect •Clients can create performance issues -
0-API: Don’t do it •Martin Fowler’s f irst rule of
distributed objects: Don’t distribute your objects •APIs take effort and create – don’t build them without good reasons •Consider non-remote APIs for internal applications •Consider Web-based UI integration for public offerings -
Summary … but if you decide to build an API:
•Consider GraphQL for special purposes •Pick (g)RPC or similar if the cost of coupling is worth it •Add some hypermedia to your HTTP APIs to make them RESTful -
Krischerstr. 100 40789 Monheim +49 2173 3366-0 Ohlauer Str. 43
10999 Berlin Ludwigstr. 180E 63067 Offenbach Kreuzstr. 16 80331 München Hermannstrasse 13 20095 Hamburg Erftstr. 15-17 50672 Köln Königstorgraben 11 90402 Nürnberg innoQ Deutschland GmbH www.innoq.com Thank you! Stefan Tilkov [email protected] +49 170 471 2625 @stilkov