Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Zend Expressive - An Introduction For API Building

Zend Expressive - An Introduction For API Building

Whether it's micro-service architectures, single-page web apps in React or Angular, or simply providing data-and-functionality-as-a-service, API development is firmly a thing today. There's plenty of advice out there about designing APIs - but how do you turn it into working, shippable code?

In this talk, Stuart will introduce you to his framework of choice for API development - Zend Expressive. He'll explain why he's gone with it, how to get started, and how to organise your code to get the best out of it. He'll also cover the essential elements that are missing (authentication, logging, metrics, validation, error handling, rate limiting), and finish by looking at how to go about testing your finished API.

Presented at Aberdeen PHP, 1st August, 2018.

Stuart Herbert

August 01, 2018
Tweet

More Decks by Stuart Herbert

Other Decks in Programming

Transcript

  1. 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
  2. @GanbaroDigital I'm here to show you how I currently use

    Zend Expressive for building API services.
  3. @GanbaroDigital In This Talk 1. Why Zend Expressive 2. Getting

    Started 3. Organising Your Code 4. Essential Elements 5. Testing Your API
  4. @GanbaroDigital I want to be able to upgrade / replace

    the framework without touching anything else.
  5. @GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Controller Features Middleware Middleware Middleware Features
  22. @GanbaroDigital It knows nothing about any other middleware. It knows

    nothing about the controller / action at the end of the pipeline.
  23. @GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic

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

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

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

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

    Controller Features Middleware Middleware Middleware Features
  28. @GanbaroDigital My Zend Expressive API apps spend around 20% in

    the 'framework' column. Reducing that overhead is important to me.
  29. @GanbaroDigital config/ data/ Config files - yours & the framework's

    Config cache home Folder Structure Created By Installer
  30. @GanbaroDigital config/ data/ public/ Config files - yours & the

    framework's Config cache home Static assets (largely unused in APIs) Folder Structure Created By Installer
  31. @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
  32. @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
  33. @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
  34. @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
  35. @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
  36. @GanbaroDigital src/ App/ src/ <code> PSR-4 Namespace starts here Folder

    Structure Created By Installer Your namespaced code Your module
  37. @GanbaroDigital src/ App/ src/ <code> ConfigProvider.php PSR-4 Namespace starts here

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

    here Folder Structure Created By Installer Your namespaced code DI container / template config Your module Your views
  39. @GanbaroDigital First thing I do is replace 'App' with a

    sensible namespace, e.g. GanbaroDigital\BillingAPI\Core
  40. @GanbaroDigital src/ Core/ Storage/ Health/ Invoices/ Payments/ Datastore abstraction Modular

    Folder Structure Health check API Business logic Dumping ground More business logic
  41. @GanbaroDigital I prefer to have each API path route to

    its own module. e.g. /u/ganbarodigital/invoices /u/ganbarodigital/payments
  42. @GanbaroDigital One of the really nice things about Zend Expressive

    is that you can have whatever structure suits you.
  43. @GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic

    Controller Features Middleware Middleware Middleware Features
  44. @GanbaroDigital Logging Needs ... 1. A logger in the DI

    container 2. Middleware to log all requests & responses 3. Middleware to add extra metadata
  45. @GanbaroDigital Have the DI container return a Monolog instance. You

    need Monolog's support for customising the logger after it has been created.
  46. @GanbaroDigital Logging Needs ... 1. A logger in the DI

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

    container 2. Middleware to log all requests & responses 3. Middleware to add extra metadata
  48. @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
  49. @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
  50. @GanbaroDigital I have my business logic throw an 'ApiError' exception.

    The business logic creates the appropriate Response and stuffs it inside the exception.
  51. @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
  52. @GanbaroDigital To catch (and log!) ApiError exceptions, I add a

    'HandleApiErrors' middleware to my app's pipeline.
  53. @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
  54. @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
  55. @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
  56. @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
  57. @GanbaroDigital Add middleware to look at the incoming Content-Type and

    validate the payload against the matching JSON schema.
  58. @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
  59. @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
  60. @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
  61. @GanbaroDigital If your API can be called directly from JavaScript

    running in browsers, you must handle authentication inside your API app.
  62. @GanbaroDigital The world is moving to JavaScript consuming APIs. And

    better data privacy laws. Add support upfront.
  63. @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
  64. @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
  65. @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
  66. @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
  67. @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
  68. @GanbaroDigital The middleware can also add headers to responses to

    tell end-users what their remaining allowance is.
  69. @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
  70. @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
  71. @GanbaroDigital In practice, per-user rate limits don't protect you when

    everyone wants to use the API at the same time.
  72. @GanbaroDigital Bootstrap Routing Dispatch Response Framework Glue Code Business Logic

    Controller Features Middleware Middleware Middleware Features