Getting Started with
OpenAPI
Matt Trask
@matthewtrask
PDX PHP - 04/20/2021
Who Am I?
Matt Trask
@matthewtrask
Senior Product Architect
Primitive - @lead_primitive
Podcast Host
APIs You Wont Hate & PHP Townhall
OSS Maintainer
openapi.tools | phptherightway.com | other things
What are we talking about?
Matt Trask
@matthewtrask
What are we talking about?
Matt Trask
@matthewtrask
What are we talking about?
Matt Trask
@matthewtrask
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8443245/5545xc.jpg)
What are we talking about?
Matt Trask
@matthewtrask
What are we talking about?
Matt Trask
@matthewtrask
November 15th, 2006
Swagger -> OpenAPI
(under the Linux Foundation)
What are we talking about?
Matt Trask
@matthewtrask
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8454504/55jmlc.jpg)
What is OpenAPI?
Matt Trask
@matthewtrask
OpenAPI is a standard way to describe HTTP-based APIs through a series of collections in a JSON/YAML form.
What is OpenAPI?
Matt Trask
@matthewtrask
- OpenAPI Specification (OAS): The industry-standard specification that outlines how OpenAPI files are structured.
- OpenAPI Definition: Your actual API definition file that represents your specific API use case. This schema is machine-readable and represented in either YAML or JSON.
-
API Documentation: The visual, human-readable representation of the API structure. Applies HTML, CSS, and JavaScript to enable API navigation and discovery.
- API Contract: An API contract IS the documentation of the API. The documentation is the place where you declare how your API will behave. In this sense it the contract between you API provider and the developers that will use it around the world.
Terms to note
Questions?
Matt Trask
@matthewtrask
New APIs or existing ones?
Questions?
Matt Trask
@matthewtrask
New APIs or existing ones?
Yes!
Questions?
Matt Trask
@matthewtrask
What is different between this and Swagger?
Questions?
Matt Trask
@matthewtrask
What is different between this and Swagger?
The name
Questions?
Matt Trask
@matthewtrask
What text formats can you use?
Questions?
Matt Trask
@matthewtrask
What text formats can you use?
YAML or JSON
(we are gonna use YAML, so fair warning)
Questions?
Matt Trask
@matthewtrask
What is new in OpenAPI v3.1.0?
Questions?
Matt Trask
@matthewtrask
What is new in OpenAPI v3.1.0?
The Webhooks Object and integration with
JSON Schema
Matt Trask
@matthewtrask
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8443523/1_vxv3XJkvHnY9NLHuj1b5bQ.png)
How you can use OpenAPI
Matt Trask
@matthewtrask
Design First API Development
Matt Trask
@matthewtrask
Design First API Development
Text
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8467011/file.png)
Matt Trask
@matthewtrask
Design First API Development Workflow
- Generating API documentation
- Automating parts of testing (APIs)
- Getting early feedback on the design of the API
- Ensuring API consistency especially if you have several API's
- Comparing API changes across versions
Matt Trask
@matthewtrask
Design First API Benefits
Less time rewriting code
Better communication across teams
Quicker Iteration
Components of the spec
Matt Trask
@matthewtrask
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8443482/OpenAPI-visual-structure-v3.png)
Components of the spec
Matt Trask
@matthewtrask
Required Sections
Info - Metadata of the API
OpenAPI - Version for tooling
Paths - The descriptions for the endpoints
Components of the spec
Matt Trask
@matthewtrask
Info/OpenAPI
# intentionally left blank
openapi: 3.1.0
title: Sample Pet Store App
summary: A pet store manager.
description: This is a sample server for a pet store.
termsOfService: https://example.com/terms/
contact:
name: API Support
url: https://www.example.com/support
email: support@example.com
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.1
Components of the spec
Matt Trask
@matthewtrask
Lets Break Down the Paths
Components of the spec
Matt Trask
@matthewtrask
![](https://media1.giphy.com/media/ncsQI9sF3pa8w/giphy.gif)
Components of the spec
Matt Trask
@matthewtrask
# intentionally left blank
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
Paths are organized by endpoint, and then by HTTP Verb
Components of the spec
Matt Trask
@matthewtrask
# intentionally left blank
# within the paths object, under the HTTP Verb for the path
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
- name: type
in: query
description: What type of pet to return (dog, cat, snake, droid)
required: false
schema:
type: string
Components of the spec
Matt Trask
@matthewtrask
# intentionally left blank
# within the paths object, under the HTTP Verb for the path
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
discriminator:
propertyName: pet_type
examples:
allOf:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
Remember the $ref is a reference pointer. This is a local reference in the example above
Components of the spec
Matt Trask
@matthewtrask
# intentionally left blank
# within the paths object, under the HTTP Verb for the path
components:
schemas:
Pet:
type: object
discriminator:
propertyName: petType
properties:
name:
type: string
petType:
type: string
required:
- name
- petType
Cat: ## "Cat" will be used as the discriminator value
description: A representation of a cat
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
properties:
huntingSkill:
type: string
description: The measured skill for hunting
enum:
- clueless
- lazy
- adventurous
- aggressive
required:
- huntingSkill
Dog: ## "Dog" will be used as the discriminator value
description: A representation of a dog
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
properties:
packSize:
type: integer
format: int32
description: the size of the pack the dog is from
default: 0
minimum: 0
required:
- packSize
Defined Keywords/Terms
Matt Trask
@matthewtrask
Specification terms to note
$ref
reference pointer to a local resource, remote resource, or a URL
Matt Trask
@matthewtrask
$ref: local
paths:
/users:
$ref: '../resources/users.yaml'
/users/{userId}:
$ref: '../resources/users-by-id.yaml'
Defined Keywords/Terms
Matt Trask
@matthewtrask
$ref: remote
paths:
/users:
$ref: '../document.json#/resources/users.yaml'
/users/{userId}:
$ref: '../document.json#/resources/users-by-id.yaml'
Defined Keywords/Terms
Matt Trask
@matthewtrask
$ref: url
paths:
/users:
$ref: 'http://path/to/your/resource.json#myElement'
/users/{userId}:
$ref: 'http://path/to/your/resource.json#myElement'
Defined Keywords/Terms
Matt Trask
@matthewtrask
Validation reference pointers
$allOf
$anyOf
$oneOf
$not
Defined Keywords/Terms
Matt Trask
@matthewtrask
Validation reference pointers
#intentionally left blank
paths:
/pets:
patch:
requestBody:
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/PetByAge'
- $ref: '#/components/schemas/PetByType'
responses:
'200':
description: Updated
components:
schemas:
PetByAge:
type: object
properties:
age:
type: integer
nickname:
type: string
required:
- age
PetByType:
type: object
properties:
pet_type:
type: string
enum: [Cat, Dog]
hunts:
type: boolean
required:
- pet_type
Defined Keywords/Terms
How can you use this with PHP?
Matt Trask
@matthewtrask
OpenAPI Initializer
https://github.com/primitivesocial/openapi-initializer
How can you use this with PHP?
Matt Trask
@matthewtrask
OpenAPI Initializer
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8477520/Screen-Shot-2021-01-14-at-5.00.50-PM.png)
How can you use this with PHP?
Matt Trask
@matthewtrask
OpenAPI Initializer
#intentionally left blank
openapi: 3.0.3
info:
title: ''
version: 0.1.0
description: 'Test API'
contact: { name: 'Laravel News', email: user@example.com, url: null }
servers:
- { url: 'http://openapi-demo.test', description: 'Local url for testing' }
tags: null
paths: null
components:
schemas: null
responses: null
headers: null
parameters: null
links: null
examples: null
How can you use this with PHP?
Matt Trask
@matthewtrask
OpenAPI HTTP Foundation Testing
https://github.com/ostell/openapi-httpfoundation-testing
How can you use this with PHP?
Matt Trask
@matthewtrask
OpenAPI HTTP Foundation Testing
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8477542/Screen_Shot_2021-04-20_at_6.51.39_AM.png)
How can you use this with PHP?
Matt Trask
@matthewtrask
OpenAPI PSR7 Validator
https://github.com/thephpleague/openapi-psr7-validator
How can you use this with PHP?
Matt Trask
@matthewtrask
OpenAPI PSR7 Validator
// intentionally left blank
<?php
$yamlFile = "api.yaml";
$jsonFile = "api.json";
$validator = (new \League\OpenAPIValidation\PSR7\ValidatorBuilder)
->fromYamlFile($yamlFile)
->getRequestValidator();
#or
$validator = (new \League\OpenAPIValidation\PSR7\ValidatorBuilder)
->fromJson(file_get_contents($jsonFile))
->getRequestValidator();
#or
$schema = new \cebe\openapi\spec\OpenApi(); // generate schema object by hand
$validator = (new \League\OpenAPIValidation\PSR7\ValidatorBuilder)
->fromSchema($schema)
->getRequestValidator();
$match = $validator->validate($request);
How can you use this with PHP?
Matt Trask
@matthewtrask
Spectator
https://github.com/hotmeteor/spectator
How can you use this with PHP?
Matt Trask
@matthewtrask
Spectator
https://github.com/hotmeteor/spectator
How can you use this with PHP?
Matt Trask
@matthewtrask
Spectator
//intentionally left blank
<?php
use Spectator/Spectator;
class ExampleTest extends TestCase
{
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
Spectator::using('Api.v1.json');
$response = $this->postJson('/user', ['name' => 'Sally']);
$response
->assertValidRequest()
->assertValidResponse(201);
}
}
Tools
Matt Trask
@matthewtrask
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8471685/Screen_Shot_2021-04-18_at_9.49.50_PM.png)
Stoplight Studio - https://stoplight.io
Tools
Matt Trask
@matthewtrask
Stoplight Studio - https://stoplight.io
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8475358/Screen_Shot_2021-04-19_at_4.12.38_PM.png)
Tools
Matt Trask
@matthewtrask
Stoplight Studio - https://stoplight.io
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8475366/Screen_Shot_2021-04-19_at_4.13.47_PM.png)
Tools
Matt Trask
@matthewtrask
![](https://s3.amazonaws.com/media-p.slid.es/uploads/392003/images/8471686/Screen_Shot_2021-04-18_at_9.51.44_PM.png)
https://openapi.tools
Matt Trask
@matthewtrask
To Wrap It Up
You can use this for new or existing APIs
Can be used for documentation, testing, validation, SDK generation
As long as the three required objects are present, you can use as much or as little of the spec as you want!
Questions?
Matt Trask
@matthewtrask
https://stoplight.io
Thanks!
Getting Started withOpenAPI
By Matt Trask
Getting Started withOpenAPI
- 284