Manual YAML writing guide (design-first approach)
This guide teaches you how to create OpenAPI specifications by hand-crafting YAML files. You’ll learn the design-first approach where you create the API documentation before (or alongside) the implementation, giving you complete control over the documentation structure and content.
Duration: 60-90 minutes Prerequisites: Basic understanding of YAML syntax and REST APIs
Overview: design-first documentation
In the design-first approach, you create the OpenAPI specification manually in YAML format, then use it to guide both development and documentation:
API Design → YAML Specification → Validation → Implementation → Testing
↓ ↓ ↓ ↓ ↓
Planning Documentation Live Preview Code Dev Accuracy Check
Step 1: understanding OpenAPI structure
Before writing YAML specifications, understand the basic OpenAPI 3.0 structure:
openapi: 3.0.1 # Version specification
info: # API metadata
title: Your API Name
version: 1.0.0
description: What your API does
servers: # Where the API is hosted
- url: http://localhost:8080
description: Development server
paths: # API endpoints
/endpoint:
get: # HTTP methods
summary: Brief description
description: Detailed explanation
responses: # Possible responses
'200':
description: Success response
components: # Reusable schemas
schemas:
ModelName: # Data models
type: object
properties:
field: type
For this tutorial, you’ll work with a Customer Management API that handles:
- Creating, reading, updating, and deleting customers
- Customer search and pagination
- Nested address information
- Different customer types (
INDIVIDUAL,BUSINESS,VIP,PREMIUM)
Step 2: setting up your YAML editor
Choose your option for configuring your YAML editor.
Option 1: Swagger editor online (recommended for learning)
- Open Swagger Editor: https://editor.swagger.io/
- Start with example: Copy the demo file to get started
# Copy the demo file content cat api-assets/openapi/examples/swagger-editor-demo.yaml - Paste and edit: Replace the content in Swagger Editor with our demo file
- Live validation: See real-time validation and preview as you edit
Option 2: online validators
- Swagger Inspector: https://inspector.swagger.io/
- OpenAPI Validator: https://validator.swagger.io/
Step 3: hands-on YAML writing tutorial
Follow these exercises to start writing YAML API specifications.
Exercise 1: complete the practice template
Start with the practice template that has TODO items for you to complete:
# Open the practice file
open api-assets/openapi/practice-exercise.yaml
Your task: Complete the TODO items in order.
Exercise 2: add complete endpoint documentation
Add POST /customers endpoint
Find the TODO:
# TODO: Add POST /customers endpoint
Add this complete endpoint:
/customers:
post:
summary: Create a new customer
description: |
Creates a new customer with complete profile information.
**Business Rules:**
- Customer ID must be unique and follow CUSTXXX format
- All required fields must be provided
- Phone numbers are validated for basic format
- Address information is required for all customer types
**Workflow:**
1. Validate customer data format
2. Check for duplicate customer ID
3. Save customer to database
4. Return success confirmation
tags:
- Customer Operations
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
examples:
individual_customer:
summary: Individual customer example
value:
id: "CUST001"
name: "Alice Johnson"
phone: "555-0123"
type: "INDIVIDUAL"
address:
street: "123 Main St"
city: "New York"
state: "NY"
zipCode: "10001"
country: "USA"
business_customer:
summary: Business customer example
value:
id: "CUST002"
name: "Acme Corporation"
phone: "555-0199"
type: "BUSINESS"
address:
street: "456 Business Ave"
city: "Chicago"
state: "IL"
zipCode: "60601"
country: "USA"
responses:
'200':
description: Customer created successfully
content:
text/plain:
schema:
type: string
example: "Customer added successfully"
'400':
description: Invalid customer data provided
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
message: "Invalid customer data: ID format must be CUSTXXX"
timestamp: "2026-01-25T10:30:00.000Z"
status: 400
error: "Bad Request"
'409':
description: Customer with this ID already exists
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
message: "Customer with ID CUST001 already exists"
timestamp: "2026-01-25T10:30:00.000Z"
status: 409
error: "Conflict"
Step 4: advanced YAML features
Once you’re comfortable writing basic YAML, try out these advanced YAML features.
Using references ($ref)
Instead of repeating schema definitions, use references:
# Define once in components
components:
schemas:
Customer:
type: object
properties:
# ... customer properties
# Reference multiple times
paths:
/customers:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Customer' # Reference
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Customer' # Reference again
Multiple examples
Provide different examples for different scenarios:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
examples:
minimal_example:
summary: Minimal required fields
description: Example with only required fields
value:
id: "CUST001"
name: "John Doe"
type: "INDIVIDUAL"
complete_example:
summary: Complete customer data
description: Example with all optional fields included
value:
id: "CUST002"
name: "Jane Smith"
phone: "555-0123"
type: "VIP"
address:
street: "123 Main St"
city: "New York"
state: "NY"
zipCode: "10001"
country: "USA"
Advanced validation
Add detailed validation rules:
Customer:
type: object
properties:
id:
type: string
pattern: '^CUST[0-9]{3}$' # Regex validation
description: Must follow format CUSTXXX
name:
type: string
minLength: 1 # Minimum length
maxLength: 100 # Maximum length
phone:
type: string
pattern: '^[0-9\-\+\(\)\s]+$' # Phone number format
email:
type: string
format: email # Built-in email validation
Step 5: validating your YAML specification
Once you’ve written your YAML specification, validation ensures it meets OpenAPI standards and will work correctly with tools.
Real-time validation in editors
- Swagger editor: Shows errors immediately in the right panel.
- VS Code with OpenAPI extension: Underlines errors with red squiggles.
- Online validators: Paste your YAML for validation.
Testing against running API
Validate your handwritten specification against the actual API:
# Start the API
./mvnw spring-boot:run
# Test your documented examples
curl -X POST http://localhost:8080/customer \
-H "Content-Type: application/json" \
-d '{
"id": "CUST001",
"name": "Alice Johnson",
"phone": "555-0123",
"type": "INDIVIDUAL",
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zipCode": "10001",
"country": "USA"
}
}'
Common validation errors
YAML Syntax Errors:
# Wrong - inconsistent indentation
info:
title: My API
version: 1.0.0 # Extra space causes error
# Correct - consistent indentation
info:
title: My API
version: 1.0.0
Missing Required Fields:
# Wrong - missing required 'info' section
openapi: 3.0.1
paths:
/test: {}
# Correct - includes required fields
openapi: 3.0.1
info:
title: Test API
version: 1.0.0
paths:
/test: {}
Invalid References:
# Wrong - reference doesn't exist
schema:
$ref: '#/components/schemas/NonexistentSchema'
# Correct - reference exists in components
components:
schemas:
Customer:
type: object
# Later in document:
schema:
$ref: '#/components/schemas/Customer'
Step 6: comparing with generated documentation
Understanding how your manual specification differs from automatically generated documentation helps you leverage the strengths of each approach.
Compare your handwritten specification with the auto-generated one:
# Get the generated specification
curl http://localhost:8080/v3/api-docs.yaml > generated-spec.yaml
# Compare with your hand-written version
diff my-api-spec.yaml generated-spec.yaml
Key differences to observe:
- Structure organization:
- Generated: Follows code structure
- Manual: Can be organized for user understanding
- Description quality
- Generated: Technical, developer-focused
- Manual: Can include business context and user guidance
-
Example completeness
Next steps
- Validate your work: Use the Testing & Validation Guide to systematically test your handwritten specifications
- Compare approaches: Try the Generated Documentation Guide to understand the code-first alternative