Slide 1

Slide 1 text

Creating Solid APIs DjangoCon Europe 2018 ⋅Rivo Laks 2018-05-23

Slide 2

Slide 2 text

Background

Slide 3

Slide 3 text

What is an API?

Slide 4

Slide 4 text

What is an API? application programming interface

Slide 5

Slide 5 text

What is an API? application programming interface application programmer interface

Slide 6

Slide 6 text

What is an API? application programming interface application programmer interface API is user interface for developers

Slide 7

Slide 7 text

What Makes an API Good?

Slide 8

Slide 8 text

What Makes an API Good? Documentation

Slide 9

Slide 9 text

What Makes an API Good? Documentation Familiarity

Slide 10

Slide 10 text

What Makes an API Good? Documentation Familiarity Lack of friction

Slide 11

Slide 11 text

Documentation Often overlooked

Slide 12

Slide 12 text

Documentation Often overlooked Gives the rst impression

Slide 13

Slide 13 text

Documentation Often overlooked Gives the rst impression The e ort is worth it!

Slide 14

Slide 14 text

Creating Awesome Docs

Slide 15

Slide 15 text

What Should Go In There?

Slide 16

Slide 16 text

What Should Go In There? How do I access it?

Slide 17

Slide 17 text

What Should Go In There? How do I access it? Do I need developer account?

Slide 18

Slide 18 text

What Should Go In There? How do I access it? Do I need developer account? Root URL, etc

Slide 19

Slide 19 text

What Should Go In There? How do I access it? Do I need developer account? Root URL, etc Authentication info

Slide 20

Slide 20 text

What Should Go In There? General encodings, formats, etc

Slide 21

Slide 21 text

What Should Go In There? General encodings, formats, etc Pagination, versioning, etc

Slide 22

Slide 22 text

What Should Go In There? General encodings, formats, etc Pagination, versioning, etc Common errors

Slide 23

Slide 23 text

What Should Go In There? General encodings, formats, etc Pagination, versioning, etc Common errors Code for getting started

Slide 24

Slide 24 text

The Endpoints

Slide 25

Slide 25 text

The Endpoints URL & operations

Slide 26

Slide 26 text

The Endpoints URL & operations Request/response data

Slide 27

Slide 27 text

The Endpoints URL & operations Request/response data Optional parameters

Slide 28

Slide 28 text

The Endpoints URL & operations Request/response data Optional parameters Permissions etc

Slide 29

Slide 29 text

Keep it Fresh!

Slide 30

Slide 30 text

Keep it Fresh! Obsolete docs are the worst

Slide 31

Slide 31 text

Keep it Fresh! Obsolete docs are the worst Always autogenerate!

Slide 32

Slide 32 text

Keep it Fresh! Obsolete docs are the worst Always autogenerate! Usually code » schema » docs

Slide 33

Slide 33 text

Schema & Autogeneration

Slide 34

Slide 34 text

Schema & Autogeneration OpenAPI, Swagger, etc

Slide 35

Slide 35 text

Schema & Autogeneration OpenAPI, Swagger, etc Use your tools

Slide 36

Slide 36 text

Schema & Autogeneration OpenAPI, Swagger, etc Use your tools Combine docs & code examples

Slide 37

Slide 37 text

Schema & Autogeneration OpenAPI, Swagger, etc Use your tools Combine docs & code examples Client libs autogeneration

Slide 38

Slide 38 text

Standardize!

Slide 39

Slide 39 text

JSON API http://jsonapi.org/ one potential standard to use

Slide 40

Slide 40 text

JSON API http://jsonapi.org/ one potential standard to use GraphQL is another option

Slide 41

Slide 41 text

Standardize Structure

Slide 42

Slide 42 text

Standardize Structure Responses have predictable, familiar structure

Slide 43

Slide 43 text

GET https://example.com/api/v1/projects { "links": { "next": "https://example.com/api/v1/projects?cursor=cD0yMDE4L", "prev": null }, "data": [...], "included": [...] }

Slide 44

Slide 44 text

"data": [ { "type": "project", "id": "289", "links": { "self": "https://example.com/api/v1/projects/289" }, "attributes": { "created": "2018-04-28T22:52:08.690486Z", "name": "Allison-Patterson", "description": "aggregate collaborative models" }, "relationships": {...} }, ... ],

Slide 45

Slide 45 text

"data": [{ ... "relationships": { "created_by": { "data": { "type": "user", "id": "199" } }, "epics": { "data": [ { "type": "epic", "id": "3101" } ], } } }, ... ],

Slide 46

Slide 46 text

"included": [ { "type": "epic", "id": "3101", "attributes": { "created": "2018-04-28T22:50:45.885691Z", "name": "Ergonomic background extranet" }, "links": { "self": "https://example.com/api/v1/epics/3101" } }, { "type": "user", "id": "199", "attributes": {...} } ]

Slide 47

Slide 47 text

Impressions?

Slide 48

Slide 48 text

Flexibility Con gurable elds: GET https://example.com/api/v1/projects GET https://example.com/api/v1/projects \ ?included=comments GET https://example.com/api/v1/projects \ ?included=comments&fields[project]=name,comments

Slide 49

Slide 49 text

Pagination List responses have next / prev links { "links": { "next": "https://example.com/api/v1/projects?cursor=cD0yMDE4L", "prev": null }, "data": [...], }

Slide 50

Slide 50 text

Pagination List responses have next / prev links { "links": { "next": "https://example.com/api/v1/projects?cursor=cD0yMDE4L", "prev": null }, "data": [...], } Cursor-base pagination FTW (but YMMV)

Slide 51

Slide 51 text

There is More ... Filtering Ordering

Slide 52

Slide 52 text

Errors

Slide 53

Slide 53 text

Errors POST https://example.com/api/v1/projects { "errors": [ { "title": "Invalid Attribute", "detail": "Name must contain at least three letters.", "source": { "pointer": "/data/attributes/name" }, "status": "422" } ] }

Slide 54

Slide 54 text

Special Cases For when you have LOTS of data

Slide 55

Slide 55 text

Special Cases For when you have LOTS of data out-of-band approach

Slide 56

Slide 56 text

GET https://example.com/api/v1/datasets/123 { "data": { "type": "dataset", "id": "123", "attributes": { "name": "CIFAR10 dataset", }, "links": { "data_tgz": "https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz", "self": "https://example.com/api/v1/datasets/123" } } }

Slide 57

Slide 57 text

Standardization Matters the speci c standard isn't that important GraphQL, etc are also good options

Slide 58

Slide 58 text

Authentication & Authorization

Slide 59

Slide 59 text

Token Authentication Clients send HTTP header, ala Authorization: Token 9944b09199c62bcf9418

Slide 60

Slide 60 text

OAuth 2.0

Slide 61

Slide 61 text

OAuth 2.0 For creating platforms

Slide 62

Slide 62 text

OAuth 2.0 For creating platforms Complex, but solves many issues

Slide 63

Slide 63 text

OAuth 2.0 For creating platforms Complex, but solves many issues Many packages, e.g. Django OAuth Toolkit, OAuthLib

Slide 64

Slide 64 text

Versioning

Slide 65

Slide 65 text

Versioning Schemes

Slide 66

Slide 66 text

Versioning Schemes AcceptHeaderVersioning (DRF) GET /projects HTTP/1.0 Accept: application/json; version=1.0

Slide 67

Slide 67 text

Versioning Schemes AcceptHeaderVersioning (DRF) GET /projects HTTP/1.0 Accept: application/json; version=1.0 URLPathVersioning (DRF) GET /v1/projects HTTP/1.0 Accept: application/json

Slide 68

Slide 68 text

Versioning Schemes Cont. Integers ( v1 ) vs dates ( 2018-05-23 )?

Slide 69

Slide 69 text

Versioning Schemes Cont. Integers ( v1 ) vs dates ( 2018-05-23 )? Dates are less emotional

Slide 70

Slide 70 text

Versioning Schemes Cont. Integers ( v1 ) vs dates ( 2018-05-23 )? Dates are less emotional Make upgrades easy

Slide 71

Slide 71 text

Version Transformers

Slide 72

Slide 72 text

Version Transformers » » Requests into newer version » » Core code is for latest version « « Responses into older version « «

Slide 73

Slide 73 text

Version Transformers » » Requests into newer version » » Core code is for latest version « « Responses into older version « « Won't work for big, breaking changes

Slide 74

Slide 74 text

tg-apicore

Slide 75

Slide 75 text

Thorgate API Core pip install tg-apicore Addon for Django REST Framework

Slide 76

Slide 76 text

Thorgate API Core pip install tg-apicore Addon for Django REST Framework Documentation generation Pre-con gured Viewset/serializer utils

Slide 77

Slide 77 text

Client's Perspective

Slide 78

Slide 78 text

The Scenario Let's try speech recognition...

Slide 79

Slide 79 text

The Scenario Let's try speech recognition... ... using AWS and GCP

Slide 80

Slide 80 text

Getting Started Documentation

Slide 81

Slide 81 text

Getting Started Documentation Quite easy to nd A bit overwhelming

Slide 82

Slide 82 text

Getting Started Documentation Quite easy to nd A bit overwhelming Code examples

Slide 83

Slide 83 text

Comprehensive Clients Install Python client GCP: google-cloud package AWS: boto3 package

Slide 84

Slide 84 text

Comprehensive Clients Install Python client GCP: google-cloud package AWS: boto3 package Authenticate

Slide 85

Slide 85 text

Comprehensive Clients Install Python client GCP: google-cloud package AWS: boto3 package Authenticate Thorough docs

Slide 86

Slide 86 text

Amazon import boto3 client = boto3.client('transcribe') response = client.start_transcription_job(...)

Slide 87

Slide 87 text

Amazon import boto3 client = boto3.client('transcribe') response = client.start_transcription_job(...) Google from google.cloud import speech client = speech.SpeechClient() results = client.recognize(...)

Slide 88

Slide 88 text

In Summary Invest in documentation Embrace standards (e.g. JSON API) Use automation Reduce friction

Slide 89

Slide 89 text

Thanks! Rivo Laks ⋅ @rivolaks ⋅ rivolaks.com Lead Engineer at Thorgate ⋅ thorgate.eu API framework for Django/DRF ⋅ tg-apicore (WIP)