Slide 1

Slide 1 text

A presentation by @stuherbert
 for @GanbaroDigital Zend Expressive An Introduction For API Building

Slide 2

Slide 2 text

Industry veteran: architect, engineer, leader, manager, mentor F/OSS contributor since 1994 Talking and writing about PHP since 2004 Chief Software Archaeologist Building Quality @GanbaroDigital About Stuart

Slide 3

Slide 3 text

Follow me I do tweet a lot about non-tech stuff though :) @stuherbert

Slide 4

Slide 4 text

@GanbaroDigital ?? ?? What framework(s) do you currently use for building APIs?

Slide 5

Slide 5 text

@GanbaroDigital Zend Expressive is my framework of choice for building JSON API services.

Slide 6

Slide 6 text

@GanbaroDigital I'm here to show you how I currently use Zend Expressive for building API services.

Slide 7

Slide 7 text

@GanbaroDigital This is just how I go about it. I'm here to learn from you too.

Slide 8

Slide 8 text

@GanbaroDigital In This Talk 1. Why Zend Expressive 2. Getting Started 3. Organising Your Code 4. Essential Elements 5. Testing Your API

Slide 9

Slide 9 text

@GanbaroDigital I won't be comparing Zend Expressive against other frameworks.

Slide 10

Slide 10 text

@GanbaroDigital Why Zend Expressive?

Slide 11

Slide 11 text

@GanbaroDigital ?? ?? How can a framework help you build your API?

Slide 12

Slide 12 text

@GanbaroDigital https://flic.kr/p/uTwoPu

Slide 13

Slide 13 text

@GanbaroDigital 1. Framework Isolation

Slide 14

Slide 14 text

@GanbaroDigital To explain what this is, let's look at what happens when your API gets called.

Slide 15

Slide 15 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 16

Slide 16 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 17

Slide 17 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 18

Slide 18 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 19

Slide 19 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 20

Slide 20 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 21

Slide 21 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 22

Slide 22 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 23

Slide 23 text

@GanbaroDigital Bootstrap Routing Dispatch Response Controller Features

Slide 24

Slide 24 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Controller Features

Slide 25

Slide 25 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Controller Features

Slide 26

Slide 26 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features

Slide 27

Slide 27 text

@GanbaroDigital I want to be able to upgrade / replace the framework without touching anything else.

Slide 28

Slide 28 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features

Slide 29

Slide 29 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features

Slide 30

Slide 30 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework v.Next Glue Code Business Logic Controller Features

Slide 31

Slide 31 text

@GanbaroDigital “Framework upgrades are very expensive. By isolating the framework, I can keep that cost under control.

Slide 32

Slide 32 text

@GanbaroDigital This means that the "glue code" can't depend on the framework.

Slide 33

Slide 33 text

@GanbaroDigital Neither can anything in the business model or data model.

Slide 34

Slide 34 text

@GanbaroDigital This has other benefits.

Slide 35

Slide 35 text

@GanbaroDigital 2. Glue Re-use

Slide 36

Slide 36 text

@GanbaroDigital “ The more time I can spend on features, the more productive I am.

Slide 37

Slide 37 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features

Slide 38

Slide 38 text

@GanbaroDigital PSR-7 / PSR-15 give me middleware and framework isolation.

Slide 39

Slide 39 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features

Slide 40

Slide 40 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 41

Slide 41 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 42

Slide 42 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 43

Slide 43 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 44

Slide 44 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 45

Slide 45 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 46

Slide 46 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 47

Slide 47 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 48

Slide 48 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 49

Slide 49 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 50

Slide 50 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 51

Slide 51 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 52

Slide 52 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 53

Slide 53 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 54

Slide 54 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 55

Slide 55 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 56

Slide 56 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 57

Slide 57 text

@GanbaroDigital Each piece of middleware is a standalone piece of logic.

Slide 58

Slide 58 text

@GanbaroDigital It knows nothing about any other middleware. It knows nothing about the controller / action at the end of the pipeline.

Slide 59

Slide 59 text

@GanbaroDigital 3. Change Isolation

Slide 60

Slide 60 text

@GanbaroDigital “ The #1 cause of new defects in working code is change.

Slide 61

Slide 61 text

@GanbaroDigital By isolating code, I can isolate the impact of code changes.

Slide 62

Slide 62 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 63

Slide 63 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 64

Slide 64 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 65

Slide 65 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 66

Slide 66 text

@GanbaroDigital I would rather repeat isolated code than have brittle DRY code.

Slide 67

Slide 67 text

@GanbaroDigital “ Today's repeated code isn't always tomorrow's repeated code.

Slide 68

Slide 68 text

@GanbaroDigital 4. Ability To Reason

Slide 69

Slide 69 text

@GanbaroDigital PHP's core strength is just how damned deterministic its execution model is.

Slide 70

Slide 70 text

@GanbaroDigital Anything that obfuscates it, or introduces non-determinism, increases your defect count.

Slide 71

Slide 71 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 72

Slide 72 text

@GanbaroDigital Everything is traceable.

Slide 73

Slide 73 text

@GanbaroDigital Everything is testable on its own.

Slide 74

Slide 74 text

@GanbaroDigital Motivations Recap 1. Framework Isolation 2. Glue Re-use 3. Change Isolation 4. Ability To Reason

Slide 75

Slide 75 text

@GanbaroDigital Zend Expressive satisfies all my motivations.

Slide 76

Slide 76 text

@GanbaroDigital Your motivations may be different. Nothing wrong with that!

Slide 77

Slide 77 text

@GanbaroDigital Getting Started

Slide 78

Slide 78 text

@GanbaroDigital https://unsplash.com/photos/RFId0_7kep4 Guided Installation

Slide 79

Slide 79 text

@GanbaroDigital composer create-project
 zendframework/zend-expressive-skeleton 


Slide 80

Slide 80 text

@GanbaroDigital Here's what I use when building JSON APIs.

Slide 81

Slide 81 text

@GanbaroDigital

Slide 82

Slide 82 text

@GanbaroDigital The modular structure helps me achieve code isolation.

Slide 83

Slide 83 text

@GanbaroDigital

Slide 84

Slide 84 text

@GanbaroDigital I haven't felt the need to try any of the others.

Slide 85

Slide 85 text

@GanbaroDigital Coding against PSR-11 means there's no obvious benefit switching between modern DI containers.

Slide 86

Slide 86 text

@GanbaroDigital

Slide 87

Slide 87 text

@GanbaroDigital My Zend Expressive API apps spend around 20% in the 'framework' column. Reducing that overhead is important to me.

Slide 88

Slide 88 text

@GanbaroDigital

Slide 89

Slide 89 text

@GanbaroDigital I don't use any templating at all (yet) in my API apps.

Slide 90

Slide 90 text

@GanbaroDigital I'm interested in creating self-documenting APIs one day. I will use Twig when that happens.

Slide 91

Slide 91 text

@GanbaroDigital

Slide 92

Slide 92 text

@GanbaroDigital We'll come back to error handling shortly.

Slide 93

Slide 93 text

@GanbaroDigital Organising Your Code

Slide 94

Slide 94 text

@GanbaroDigital Zend Expressive uses a different layout than (say) Wordpress.

Slide 95

Slide 95 text

@GanbaroDigital Folder Structure Created By Installer

Slide 96

Slide 96 text

@GanbaroDigital config/ Config files - yours & the framework's Folder Structure Created By Installer

Slide 97

Slide 97 text

@GanbaroDigital config/ data/ Config files - yours & the framework's Config cache home Folder Structure Created By Installer

Slide 98

Slide 98 text

@GanbaroDigital config/ data/ public/ Config files - yours & the framework's Config cache home Static assets (largely unused in APIs) Folder Structure Created By Installer

Slide 99

Slide 99 text

@GanbaroDigital In something like Wordpress, everything lives in the 'public' folder AKA the DocRoot

Slide 100

Slide 100 text

@GanbaroDigital config/ data/ public/ src/ Config files - yours & the framework's Config cache home Static assets (largely unused in APIs) Your glue code and business logic Folder Structure Created By Installer

Slide 101

Slide 101 text

@GanbaroDigital config/ data/ public/ src/ test/ Config files - yours & the framework's Config cache home Static assets (largely unused in APIs) Your glue code and business logic Unit tests for what's in src/ Folder Structure Created By Installer

Slide 102

Slide 102 text

@GanbaroDigital config/ data/ public/ src/ test/ vendor/ Config files - yours & the framework's Config cache home Static assets (largely unused in APIs) Your glue code and business logic Unit tests for what's in src/ Packages installed via composer Folder Structure Created By Installer

Slide 103

Slide 103 text

@GanbaroDigital Zend Expressive uses PSR-4 autoloading to load each module in your app.

Slide 104

Slide 104 text

@GanbaroDigital config/ data/ public/ src/ test/ vendor/ Config files - yours & the framework's Config cache home Static assets (largely unused in APIs) Your glue code and business logic Unit tests for what's in src/ Packages installed via composer Folder Structure Created By Installer

Slide 105

Slide 105 text

@GanbaroDigital config/ data/ public/ src/ test/ vendor/ Config files - yours & the framework's Config cache home Static assets (largely unused in APIs) Your glue code and business logic Unit tests for what's in src/ Packages installed via composer Folder Structure Created By Installer

Slide 106

Slide 106 text

@GanbaroDigital src/ Folder Structure Created By Installer

Slide 107

Slide 107 text

@GanbaroDigital src/ App/ Folder Structure Created By Installer Your module

Slide 108

Slide 108 text

@GanbaroDigital src/ App/ src/ PSR-4 Namespace starts here Folder Structure Created By Installer Your module

Slide 109

Slide 109 text

@GanbaroDigital { ..., "autoload": "psr-4": { "App\\": "src/App/src" } }, ... }

Slide 110

Slide 110 text

@GanbaroDigital src/ App/ src/ PSR-4 Namespace starts here Folder Structure Created By Installer Your namespaced code Your module

Slide 111

Slide 111 text

@GanbaroDigital src/ App/ src/ ConfigProvider.php PSR-4 Namespace starts here Folder Structure Created By Installer Your namespaced code DI container / template config Your module

Slide 112

Slide 112 text

@GanbaroDigital src/ App/ src/ ConfigProvider.php templates/ PSR-4 Namespace starts here Folder Structure Created By Installer Your namespaced code DI container / template config Your module Your views

Slide 113

Slide 113 text

@GanbaroDigital First thing I do is replace 'App' with a sensible namespace, e.g. GanbaroDigital\BillingAPI\Core

Slide 114

Slide 114 text

@GanbaroDigital src/ App/ Modular Folder Structure

Slide 115

Slide 115 text

@GanbaroDigital src/ App/ Modular Folder Structure

Slide 116

Slide 116 text

@GanbaroDigital src/ Core/ Modular Folder Structure Dumping ground

Slide 117

Slide 117 text

@GanbaroDigital Then I add modules to provide functionality to business logic.

Slide 118

Slide 118 text

@GanbaroDigital src/ Core/ Storage/ Health/ Datastore abstraction Modular Folder Structure Health check API Dumping ground

Slide 119

Slide 119 text

@GanbaroDigital And modules for individual business logic areas.

Slide 120

Slide 120 text

@GanbaroDigital src/ Core/ Storage/ Health/ Invoices/ Payments/ Datastore abstraction Modular Folder Structure Health check API Business logic Dumping ground More business logic

Slide 121

Slide 121 text

@GanbaroDigital I prefer to have each API path route to its own module. e.g. /u/ganbarodigital/invoices /u/ganbarodigital/payments

Slide 122

Slide 122 text

@GanbaroDigital One of the really nice things about Zend Expressive is that you can have whatever structure suits you.

Slide 123

Slide 123 text

@GanbaroDigital Essential Elements

Slide 124

Slide 124 text

@GanbaroDigital Zend Expressive provides a great platform for building API services.

Slide 125

Slide 125 text

@GanbaroDigital Out of the box, it isn't a 100% ready-to-go API framework.

Slide 126

Slide 126 text

@GanbaroDigital Most of what we need can be handled by building some middleware.

Slide 127

Slide 127 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 128

Slide 128 text

@GanbaroDigital A couple of things need adding as services built by the DI container.

Slide 129

Slide 129 text

@GanbaroDigital Logging

Slide 130

Slide 130 text

@GanbaroDigital https://speakerdeck.com/stuartherbert/designing-for- disaster-preparing-your-code-for-emergencies

Slide 131

Slide 131 text

@GanbaroDigital Logging Needs ... 1. A logger in the DI container 2. Middleware to log all requests & responses 3. Middleware to add extra metadata

Slide 132

Slide 132 text

@GanbaroDigital Use: Psr\Log\LoggerInterface as the request key into the DI container.

Slide 133

Slide 133 text

@GanbaroDigital Have the DI container return a Monolog instance. You need Monolog's support for customising the logger after it has been created.

Slide 134

Slide 134 text

@GanbaroDigital i.e. an 'immutable' logger is about as much use as a chocolate fireguard here!

Slide 135

Slide 135 text

@GanbaroDigital Gradually add metadata fields to help you find relevant logs. Think of them like database indexes.

Slide 136

Slide 136 text

@GanbaroDigital Add a 'uid' metadata: unique ID for that API request

Slide 137

Slide 137 text

@GanbaroDigital Logging Needs ... 1. A logger in the DI container 2. Middleware to log all requests & responses 3. Middleware to add extra metadata

Slide 138

Slide 138 text

@GanbaroDigital LogRequestsAndResponses: middleware to add initial metadata to the logger & capture inputs and outputs

Slide 139

Slide 139 text

@GanbaroDigital Add a 'request-id' metadata: trace API calls across your architecture.

Slide 140

Slide 140 text

@GanbaroDigital Logging Needs ... 1. A logger in the DI container 2. Middleware to log all requests & responses 3. Middleware to add extra metadata

Slide 141

Slide 141 text

@GanbaroDigital In the Authentication middleware, add a 'user-id' to the logger's metadata.

Slide 142

Slide 142 text

@GanbaroDigital Error Handling

Slide 143

Slide 143 text

@GanbaroDigital Error Handling Needs ... 1. Common code for RFC 7807 responses 2. Common exception for error responses 3. Middleware to handle the common exception 4. Middleware for 404 Not Found handling

Slide 144

Slide 144 text

@GanbaroDigital RFC 7807 defines a common format for API responses when an error has occurred.

Slide 145

Slide 145 text

@GanbaroDigital Error Handling Needs ... 1. Common code for RFC 7807 responses 2. Common exception for error responses 3. Middleware to handle the common exception 4. Middleware for 404 Not Found handling

Slide 146

Slide 146 text

@GanbaroDigital I have my business logic throw an 'ApiError' exception. The business logic creates the appropriate Response and stuffs it inside the exception.

Slide 147

Slide 147 text

@GanbaroDigital https://speakerdeck.com/stuartherbert/
 5-patterns-to-improve-application-robustness

Slide 148

Slide 148 text

@GanbaroDigital Error Handling Needs ... 1. Common code for RFC 7807 responses 2. Common exception for error responses 3. Middleware to handle the common exception 4. Middleware for 404 Not Found handling

Slide 149

Slide 149 text

@GanbaroDigital To catch (and log!) ApiError exceptions, I add a 'HandleApiErrors' middleware to my app's pipeline.

Slide 150

Slide 150 text

@GanbaroDigital Error Handling Needs ... 1. Common code for RFC 7807 responses 2. Common exception for error responses 3. Middleware to handle the common exception 4. Middleware for 404 Not Found handling

Slide 151

Slide 151 text

@GanbaroDigital I add a 'NotFoundHandler' to generate RFC 7807 responses for HTTP 404 errors.

Slide 152

Slide 152 text

@GanbaroDigital Validation

Slide 153

Slide 153 text

@GanbaroDigital Validation Needs ... 1. application/vnd+ Content-Type 2. JSON schema for input payloads 3. Middleware to validate against JSON schema 4. (optional) JSON schema for output payloads

Slide 154

Slide 154 text

@GanbaroDigital I don't use application/json as my API Content-Type.

Slide 155

Slide 155 text

@GanbaroDigital application/vnd+billingapi.invoice.v1

Slide 156

Slide 156 text

@GanbaroDigital Validation Needs ... 1. application/vnd+ Content-Type 2. JSON schema for input payloads 3. Middleware to validate against JSON schema 4. (optional) JSON schema for output payloads

Slide 157

Slide 157 text

@GanbaroDigital https://speakerdeck.com/stuartherbert/
 json-schema-for-validating-api-requests

Slide 158

Slide 158 text

@GanbaroDigital Validation Needs ... 1. application/vnd+ Content-Type 2. JSON schema for input payloads 3. Middleware to validate against JSON schema 4. (optional) JSON schema for output payloads

Slide 159

Slide 159 text

@GanbaroDigital Add middleware to look at the incoming Content-Type and validate the payload against the matching JSON schema.

Slide 160

Slide 160 text

@GanbaroDigital Validation Needs ... 1. application/vnd+ Content-Type 2. JSON schema for input payloads 3. Middleware to validate against JSON schema 4. (optional) JSON schema for output payloads

Slide 161

Slide 161 text

@GanbaroDigital The same middleware can also validate all of your API responses.

Slide 162

Slide 162 text

@GanbaroDigital Authentication

Slide 163

Slide 163 text

@GanbaroDigital Authentication Needs ... 1. An identity provider 2. Middleware to handle CORS requests 3. Middleware to authenticate a user 4. Middleware to authorise a user

Slide 164

Slide 164 text

@GanbaroDigital An identity provider is a user database + UI all in one.

Slide 165

Slide 165 text

@GanbaroDigital A commercial one like auth0.com might be easier than building your own.

Slide 166

Slide 166 text

@GanbaroDigital Authentication Needs ... 1. An identity provider 2. Middleware to handle CORS requests 3. Middleware to authenticate a user 4. Middleware to authorise a user

Slide 167

Slide 167 text

@GanbaroDigital The CORS spec mandates that some CORS-requests are always unauthenticated.

Slide 168

Slide 168 text

@GanbaroDigital If your API can be called directly from JavaScript running in browsers, you must handle authentication inside your API app.

Slide 169

Slide 169 text

@GanbaroDigital The world is moving to JavaScript consuming APIs. And better data privacy laws. Add support upfront.

Slide 170

Slide 170 text

@GanbaroDigital Authentication Needs ... 1. An identity provider 2. Middleware to handle CORS requests 3. Middleware to authenticate a user 4. Middleware to authorise a user

Slide 171

Slide 171 text

@GanbaroDigital Use separate middleware items for authentication and authorisation.

Slide 172

Slide 172 text

@GanbaroDigital Authentication Needs ... 1. An identity provider 2. Middleware to handle CORS requests 3. Middleware to authenticate a user 4. Middleware to authorise a user

Slide 173

Slide 173 text

@GanbaroDigital Keep authorisation simple. Use OAuth2 scopes, not RBAC.

Slide 174

Slide 174 text

@GanbaroDigital In practice, RBAC schemes perform very poorly.

Slide 175

Slide 175 text

@GanbaroDigital Metrics

Slide 176

Slide 176 text

@GanbaroDigital Metrics Need ... 1. Metrics infrastructure (e.g. Prometheus) 2. A statsd client

Slide 177

Slide 177 text

@GanbaroDigital https://speakerdeck.com/stuartherbert/designing-for- disaster-preparing-your-code-for-emergencies

Slide 178

Slide 178 text

@GanbaroDigital There's no PSR for a metrics client today.

Slide 179

Slide 179 text

@GanbaroDigital Add your preferred metrics client to the DI container.

Slide 180

Slide 180 text

@GanbaroDigital Call the client throughout your code to report timings and counters.

Slide 181

Slide 181 text

@GanbaroDigital Don't use middleware to track your API response times. Get these timings from your Nginx logs.

Slide 182

Slide 182 text

@GanbaroDigital Rate Limiting

Slide 183

Slide 183 text

@GanbaroDigital Most APIs need to protect themselves from their heaviest users.

Slide 184

Slide 184 text

@GanbaroDigital A common approach is to limit the number of requests per user, per time period.

Slide 185

Slide 185 text

@GanbaroDigital Rate Limiting Needs ... 1. Identity provider to provide user IDs 2. Redis to track API usage 3. Middleware to update API usage 4. Cron job to reset API usage 5. Auto-scaling infrastructure

Slide 186

Slide 186 text

@GanbaroDigital Rate Limiting Needs ... 1. Identity provider to provide user IDs 2. Redis to track API usage 3. Middleware to update API usage 4. Cron job to reset API usage 5. Auto-scaling infrastructure

Slide 187

Slide 187 text

@GanbaroDigital Redis gives us atomic increment / decrement.

Slide 188

Slide 188 text

@GanbaroDigital Using an external store like Redis makes auto-scaling possible.

Slide 189

Slide 189 text

@GanbaroDigital Rate Limiting Needs ... 1. Identity provider to provide user IDs 2. Redis to track API usage 3. Middleware to update API usage 4. Cron job to reset API usage 5. Auto-scaling infrastructure

Slide 190

Slide 190 text

@GanbaroDigital Add middleware to decrement per-user rate allowance and return errors when the allowance is used up.

Slide 191

Slide 191 text

@GanbaroDigital The middleware can also add headers to responses to tell end-users what their remaining allowance is.

Slide 192

Slide 192 text

@GanbaroDigital Rate Limiting Needs ... 1. Identity provider to provide user IDs 2. Redis to track API usage 3. Middleware to update API usage 4. Cron job to reset API usage 5. Auto-scaling infrastructure

Slide 193

Slide 193 text

@GanbaroDigital Easiest way to give the end-user their next allowance is from a cron job or equivalent.

Slide 194

Slide 194 text

@GanbaroDigital Don't build cron features into your API service. Use the real thing.

Slide 195

Slide 195 text

@GanbaroDigital Rate Limiting Needs ... 1. Identity provider to provide user IDs 2. Redis to track API usage 3. Middleware to update API usage 4. Cron job to reset API usage 5. Auto-scaling infrastructure

Slide 196

Slide 196 text

@GanbaroDigital In practice, per-user rate limits don't protect you when everyone wants to use the API at the same time.

Slide 197

Slide 197 text

@GanbaroDigital Auto-scaling infrastructure is your friend there.

Slide 198

Slide 198 text

@GanbaroDigital Testing APIs

Slide 199

Slide 199 text

@GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic Controller Features Middleware Middleware Middleware Features

Slide 200

Slide 200 text

@GanbaroDigital Write unit tests for individual components.

Slide 201

Slide 201 text

@GanbaroDigital Write end-to-end tests for the API as a whole.

Slide 202

Slide 202 text

@GanbaroDigital https://getpostman.com

Slide 203

Slide 203 text

Thank You Can We Help You? A presentation by @stuherbert
 for @GanbaroDigital