Slide 1

Slide 1 text

API Documentation and Tooling with OpenAPI CakeFest 2020 | Chris Nizzardini

Slide 2

Slide 2 text

Introduction About me Started coding in 2006 and developing with CakePHP in 2010. API experience - Personal/startup projects - Open Source - Private/commercial - Public/government Chris Nizzardini | @cnizzardini API Documentation and Tooling with OpenAPI

Slide 3

Slide 3 text

Postman State of the API Report (2019) ● 57% of respondents have 3 years or less API development experience. ● Over 60% spends 10 hours or more per week on API development. ● API usage is split almost evenly between internal (52%) and external. ● More than half said API documentation is either below average or not documented well at all. ● The most helpful enhancement API producers can make is to provide better examples in the documentation (63.5%), followed by standardization (59.4%), and sample code (57.8%). Source: https://www.postman.com/resources/infographics/api-survey-2019/

Slide 4

Slide 4 text

Reasons we’re not maintaining documentation ● Manual process ○ Tedious ○ Time consuming ○ Can become dated quickly depending on release cycles ○ We never built any and it’s too much work now. ● Not a priority ○ Doesn’t add revenue ○ We don’t have the time ● We simply don’t know how ● We don’t care enough for all the reasons above

Slide 5

Slide 5 text

Changing perceptions on documentation ● Developer experience matters ○ Onboarding internal engineers ○ Streamline implementation of your commercial API for external developers ● Support inquiries cost money ○ Reduce support inquiries with a well documented API ● Your documentation is the user interface for your API ○ A website with an ugly UI is a red flag and so is an API without good documentation ● Marketing matters and documentation is marketing ● We can “automate” portions of our documentation with OpenAPI tooling

Slide 6

Slide 6 text

OpenAPI 3.0 ● Specification for describing RESTful API requests, response, schema etc. ● Formally known as Swagger (1.0 - 2.0) ● YAML / JSON ● Has a robust tooling ecosystem: ○ SwaggerUI ○ Redoc ○ Client Generators ○ OpenAPI schema can be imported directly into Postman

Slide 7

Slide 7 text

OpenAPI Overview ● API Information ○ Title, Description, Version ● Paths ○ Operations (HTTP GET, POST, PATCH, PUT, DELETE, OPTIONS) ■ Requests ■ Responses ● Components ○ Schemas ○ Parameters ● Extensibility ○ x-vendor extensions for customization

Slide 8

Slide 8 text

openapi: 3.0.0 info: version: 1.0 title: My API description: | Yes multiple lines are permitted if you use a pipe. license: name: MIT License servers: - url: https://foo.com/api OpenAPI - Information

Slide 9

Slide 9 text

OpenAPI - Path paths: /cities: post: # ... patch: # ... put: # ... get: # ... delete: # ...

Slide 10

Slide 10 text

OpenAPI - POST post: summary: Add a City requestbody: content: application:x-www-form-urlencoded: schema: $ref: ‘#/components/schemas/City’ application:json: schema: $ref: ‘#/components/schemas/City’ responses: ‘200’: description: ‘Successfully created City’ content: application/json: schema: $ref: ‘#/components/schemas/City’

Slide 11

Slide 11 text

OpenAPI - GET get: parameters: — name: ‘sort’ in: query schema: type: string enum: — name — created — $ref: ‘#/components/parameters/PaginatorPage’ — $ref: ‘#/components/parameters/PaginatorLimit’ — $ref: ‘#/components/parameters/PaginatorDirection’ responses: ‘200’: content: application/json: schema: type: array items: $ref: ‘#/components/schemas/City’

Slide 12

Slide 12 text

OpenAPI - Schema components: schemas: City: type: object properties: id: type: integer format: int64 # format is optional, can specify things like date-time, email etc... readOnly: true name: type: string minLength: 1 maxLength: 64 country: $ref: ‘#/components/schemas/Country’ # reference other OpenAPI schemas

Slide 13

Slide 13 text

OpenAPI - Vendor Extensions x-custom: components: schemas: City-Write: type: object properties: name: type: string City-Add: type: object required: — name allOf: — $ref: ‘#/x-custom/components/schemas/City-Write’ Custom vendor extensions do not appear in Swagger or Redoc (though each have their own extensions). We can use these to provide custom schema and parameters and avoid cluttering documentation views.

Slide 14

Slide 14 text

OpenAPI Tools ● Online Editor https://editor.swagger.io ○ WYSIWG editor, validates schema, converts OpenAPI JSON to YAML. ○ Generate clients and servers from OpenAPI schema. ● OpenAPI Generator (NPM) https://openapi-generator.tech ○ openapi-generator generate -g php -o ~/php-client -i ~/openapi.yaml --skip-validate-spec ● OpenAPI Tools https://openapi.tools

Slide 15

Slide 15 text

Building OpenAPI with Annotations ● Most languages have libraries for OpenAPI annotations ● Vanilla PHP ○ zircote/swagger-php ● Framework adaptations ○ CakePHP: alt3/cakephp-swagger ○ Laravel, Symfony, Yii etc.

Slide 16

Slide 16 text

alt3/cakephp-swagger /** * @SWG\Get( * path="/cities", * summary="Retrieve a list of cities", * produces={"application/json"}, * @SWG\Parameter(name="sort",in="query",required=false,type="string"), * @SWG\Response( * response="200", * description="Successful operation", * @SWG\Schema(type="object",ref="#/components/schemas/Cities") * ) * ) */ public function index() { // ...code }

Slide 17

Slide 17 text

But this all too manual and tedious for me! ● Why can’t my existing $x be converted into OpenAPI? ○ $x = routes ○ $x = schema ○ $x = query parameters ○ $x = project meta-data (e.g. doc blocks) ○ $x = data transfer objects ○ $x = authentication (security) ● Symfony API Platform (php), FastAPI (python), Spring (java) and others can...

Slide 18

Slide 18 text

Wait...I thought this was a Cake Fest?!?! ● Why can’t my existing CakePHP be converted into OpenAPI? ○ We already have: ■ RESTful routes ■ Controllers ■ Models ■ Validations ■ Doc Blocks ■ Data Transfer Objects ■ Authorization ■ Pagination ● So just bake it for me. Okay...

Slide 19

Slide 19 text

cnizzardini/cakephp-swagger-bake /** * List Cities * * Returns a list of Cities */ public function index() { // ...controller action code } get: summary: ‘List Cities’ description: ‘Returns a list of Cities’ responses: ‘200’: content: application/json: schema: type: array items: $ref: ‘#/components/schemas/City’

Slide 20

Slide 20 text

More Doc Blocks please /** * List Cities * * @see https://foo.bar/docs Desc... * @throws MethodNotAllowedException * @deprecated */ public function index() { // ...code } get: summary: ‘List Cities’ deprecated: true externalDocs: url: https://foo.bar/docs description: Desc... responses: ‘200’: content: application/json: schema: type: array items: $ref: ‘#/components/schemas/City’ ‘405’: description: Method Not Allowed content: application/json: schema: $ref: ‘#/components/schemas/Exception’

Slide 21

Slide 21 text

CakePHP Swagger Bake - Annotations /** * List Cities * * Returns a list of Cities * * @Swag\SwagPaginator() */ public function index() { // ...code } get: summary: ‘List Cities’ description: ‘Returns a list of Cities’ parameters: — name: ‘sort’ in: query schema: type: string enum: — id — name — created — $ref: ‘#/x-swag/components/parameters/PaginatorPage’ — $ref: ‘#/x-swag/components/parameters/PaginatorLimit’ — $ref: ‘#/x-swag/components/parameters/PaginatorDirection’

Slide 22

Slide 22 text

And that got me thinking... What else could the Cake community use for API development? ● CRUD Exceptions ● Response Formats: HAL+JSON and JSON-LD ● RESTful baking themes ● Auto routing ● Could we use a plugin specifically designed for API development?

Slide 23

Slide 23 text

More Cake? Okay MixerAPI MixerAPI.com | Streamlining API Development ● OpenAPI generator ● RESTful Bake Theme ● Exception Renderer ● Response Format: HAL+JSON and JSON-LD ● Route Builder ● @todo: ○ App Skeleton / Docker Compose ○ Contributions from the community

Slide 24

Slide 24 text

Happy Baking Github: https://github.com/cnizzardini Twitter: @cnizzardini CakePHP Slack: cnizzardini