Crystal clear service interfaces with Swagger/OpenAPI
@scott_triglia
Swagger
Yelp’s Mission:Connecting people with great
local businesses.
@scott_triglia
I work with 💵💶
Let’s talk some hard truths about APIs
Writing a good API is hard
The average API is functional, but not excellent
CC BY 2.0 by alebonvini
The average API is not well-documented
CC BY 2.0 by suigetsu
CC BY 2.0 by gpoo
The average API is ambiguous or under specified
The average API is written in a rush
The average API does not get a dedicated team
The average API is
The average API is average!
My job: make a widget
Their job: make a great API
Backend engineers make a lot of APIs
We need better tools
We need more leverage
CC BY-NC-SA 2.0 by ilri
CC BY-SA 3.0 by Michael Gäbler
We need our APIs to document
themselves
We need our APIs to validate
themselves
We need our APIs to manage
themselves
We need something like
Lessons from production
A Swagger/OpenAPI spec describes a REST API
A Swagger spec is a concrete description of a REST API
And I mean *very* concrete
* Request Methods + URIs * Query, Path, Body params * Headers * Responses
Explicit API spec
Awesome FeaturesSwagger
Libraries
Documentation benefits
Server-side benefits
Server side - striglia/pyramid_swagger# In your Pyramid webapp.pyconf[‘pyramid_swagger.schema_directory'] = ‘api/‘config.include(‘pyramid_swagger')
And note that we can do this on client or server!
Client side - Yelp/bravadofrom bravado.client import SwaggerClient
client = SwaggerClient.from_url( “http://www.striglia.io/swagger.json”)pet = client.users.get(active_only=True).result()
And across languages!
GET /swagger.yaml
Production Pro-Tips
API-first design keeps you sane
Documenting a service’s API can be challenging
Doing it as a design exercise is pretty easy
Doing it retroactively can be horrific
For your sanity, try EXTREMELY hard to enforce the creation of these specs up front, not after the fact.
How do we distribute Swagger specs?
Easiest solution — local to service, served over HTTP for free by tooling
Problems: HTTP is unreliable and slow
Problems: What if there are N versions of the
API in the wild at once?
Client
Service Version A
#users
Call #1: Ask for spec Call #2: Get #users reference
Service Version A
#users
1
2
Client
Service Version A
#users
Call #1: Ask for spec Call #2: Get #users ref Call #3: Get #orders ref
Service Version B
#users
1
2
#orders
3
Hacky approach — make your specs one huge document
Yelp’s direction — auto-packaged client libraries built on spec changes
https://github.com/civisanalytics/swagger-diff
Upside: no perf hit from JIT spec fetching
over the network
Upside: clients explicitly expect a
particular interface
Upside: a convenient place to inject other smart behavior (e.g. OpenTracing
headers)
Good APIs are complicated!
Swagger lets you declaratively design APIs
Validation + Documentation come for free
And it’s all language agnostic
Raise the bar on the quality of your APIs
* Spec -> www.swagger.io * Help -> www.swagger.io/irc/
* Client: Yelp/bravado * Server: striglia/pyramid_swagger
@YelpEngineering
fb.com/YelpEngineers
engineeringblog.yelp.com
github.com/yelp
[email protected] @scott_triglia