http clients and apis
OpenAPI Documentation
OpenAPI is a standard for documenting HTTP APIs. It describes paths, methods, parameters, request bodies, response bodies, status codes, authentication, and examples.
Good OpenAPI documentation is a contract. Client developers use it to understand what to send and what to expect back. Tools can use it to generate documentation, clients, server stubs, and contract tests.
What an operation describes
<?php
declare(strict_types=1);
$operation = [
'method' => 'GET',
'path' => '/products/{id}',
'response' => ['id' => 'integer', 'name' => 'string'],
];
echo $operation['method'] . ' ' . $operation['path'] . PHP_EOL;
echo json_encode($operation['response'], JSON_THROW_ON_ERROR) . PHP_EOL;
// Prints:
// GET /products/{id}
// {"id":"integer","name":"string"}
An OpenAPI operation usually documents:
- HTTP method and path
- path parameters, such as
{id} - query parameters, such as
page - request body schema
- response schemas by status code
- authentication requirements
- examples
- error responses
A small OpenAPI-style structure
This is a simplified PHP array representing a tiny piece of an OpenAPI document:
<?php
declare(strict_types=1);
$document = [
'openapi' => '3.1.0',
'paths' => [
'/products/{id}' => [
'get' => [
'summary' => 'Fetch one product',
'parameters' => [
['name' => 'id', 'in' => 'path', 'required' => true, 'schema' => ['type' => 'integer']],
],
'responses' => [
'200' => ['description' => 'Product found'],
'404' => ['description' => 'Product not found'],
],
],
],
],
];
echo $document['openapi'] . ' ' . array_key_first($document['paths']) . PHP_EOL;
// Prints:
// 3.1.0 /products/{id}
Real OpenAPI is usually written as YAML or JSON, not PHP arrays. PHP arrays are used here only to keep examples runnable.
Schemas describe bodies
OpenAPI schemas describe request and response bodies. They are close to JSON Schema.
Product:
type: object
required: [id, name]
properties:
id:
type: integer
name:
type: string
Schemas should match the JSON your PHP code actually returns. If the code returns name but the docs say title, clients will break.
Examples matter
Good examples make APIs easier to use. They should be realistic, valid, and kept in sync with schemas.
<?php
declare(strict_types=1);
$example = [
'data' => [
'id' => 123,
'name' => 'Notebook',
],
];
echo json_encode($example, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . PHP_EOL;
// Prints:
// {
// "data": {
// "id": 123,
// "name": "Notebook"
// }
// }
Documentation drift
Documentation drift happens when the docs and the code disagree. It is one of the biggest risks with OpenAPI.
Common causes:
- response fields renamed in code but not docs
- status codes changed without updating docs
- validation rules tightened without updating schemas
- examples left stale after a feature change
- error responses undocumented
Teams reduce drift with contract tests, generated docs from code, code generated from specs, or review checklists that include API docs.
Authentication documentation
OpenAPI can document authentication schemes such as bearer tokens, API keys, OAuth, or Basic auth. This is important because clients need to know where credentials go and what failures look like.
Do not document secrets in examples. Use placeholder values.
What to check in a project
Check whether OpenAPI is the source of truth or generated from code.
Check that every public endpoint documents success and error responses.
Check that schemas match actual JSON response shapes.
Check that examples are valid and realistic.
Check that authentication and rate-limit responses are documented.
Check changes for backwards compatibility before updating published contracts.
What you should be able to do
After this lesson, you should be able to explain what OpenAPI documents, recognise operation and schema sections, understand documentation drift, and review whether API documentation matches PHP endpoint behaviour.
Practice
Task: Sketch An OpenAPI Operation
Write a small PHP array that represents the important parts of an OpenAPI operation for GET /products/{id}.
Requirements
- Use
declare(strict_types=1);. - Include method and path.
- Include a required path parameter named
id. - Include documented
200and404responses. - Include a product example for the
200response. - Print a short summary of the operation.
Check Your Work
Run the script and confirm the summary mentions the path, parameter, and response statuses.
Show solution
This solution keeps the operation small but includes the parts clients need most.
<?php
declare(strict_types=1);
$operation = [
'method' => 'GET',
'path' => '/products/{id}',
'parameters' => [
['name' => 'id', 'in' => 'path', 'required' => true, 'schema' => ['type' => 'integer']],
],
'responses' => [
'200' => [
'description' => 'Product found',
'example' => ['data' => ['id' => 123, 'name' => 'Notebook']],
],
'404' => [
'description' => 'Product not found',
'example' => ['errors' => [['code' => 'not_found', 'message' => 'Product not found.']]],
],
],
];
echo $operation['method'] . ' ' . $operation['path'] . PHP_EOL;
echo 'Parameter: ' . $operation['parameters'][0]['name'] . PHP_EOL;
echo 'Responses: ' . implode(', ', array_keys($operation['responses'])) . PHP_EOL;
// Prints:
// GET /products/{id}
// Parameter: id
// Responses: 200, 404
Why This Works
The operation tells clients how to call the endpoint and what success and missing-resource responses look like.