Exercise #1: Basic OpenAPI Specification
Learn how to create a basic OpenAPI specification for a simple weather API
Exercise Description
In this exercise, you will create a basic OpenAPI 3.0 specification for a simple weather API that allows users to get current weather conditions and forecasts for a city. This exercise will help you understand the structure of OpenAPI documents and how to document API endpoints, parameters, responses, and schemas.
- Understand the structure of OpenAPI 3.0 specifications
- Document API endpoints and their parameters
- Define request and response schemas
- Add examples and descriptions to make the API more user-friendly
- Create a specification that can be rendered with Swagger UI
API Requirements
The weather API you will document should include the following endpoints:
1. Get the current weather for a city:
GET /weather/current/{city}
2. Get a 5-day forecast for a city:
GET /weather/forecast/{city}
3. Get historical weather data for a city:
GET /weather/history/{city}
Parameters
Parameter | Type | Location | Required | Description |
---|---|---|---|---|
city |
string | path | Yes | The name of the city to get weather information for |
units |
string | query | No | Units of measurement. Options: metric (default), imperial |
lang |
string | query | No | Language for weather descriptions. Default: en |
days |
integer | query | No | Number of days for historical data (1-30). Only applicable for the history endpoint. |
Example Response
Current Weather Response
{
"city": "London",
"country": "GB",
"timestamp": "2023-05-15T12:00:00Z",
"weather": {
"temperature": 18.5,
"feels_like": 17.8,
"humidity": 65,
"pressure": 1012,
"description": "Partly cloudy",
"wind": {
"speed": 12.5,
"direction": "SW"
}
}
}
Your Task
Create a complete OpenAPI 3.0 specification in YAML format that documents the weather API described above. Your specification should include:
- API information (title, description, version, etc.)
- Server information
- Path definitions for all three endpoints
- Parameter definitions (path and query parameters)
- Response schemas for all endpoints
- Component schemas for reusable objects
- Examples for requests and responses
- Descriptions for all components to make the API user-friendly
You can use the Swagger Editor to create and validate your OpenAPI specification. It provides real-time validation and a preview of how your documentation will look.
Submission Guidelines
To complete this exercise:
- Create a YAML file containing your OpenAPI specification
- Validate your specification using the Swagger Editor or another OpenAPI validator
- Save the file as
weather-api.yaml
- Create a README.md file explaining your design decisions and any assumptions you made
Optional: Deploy your API documentation using a tool like GitHub Pages or Redocly and include the link in your README.md.
Example Solution
Here's an example OpenAPI specification for the weather API:
openapi: 3.0.3
info:
title: Weather API
description: |
A simple API for retrieving weather information for cities around the world.
This API provides current weather conditions, forecasts, and historical data.
version: 1.0.0
contact:
name: API Support
email: support@weatherapi.example.com
url: https://www.weatherapi.example.com/support
servers:
- url: https://api.weatherapi.example.com/v1
description: Production server
- url: https://dev.weatherapi.example.com/v1
description: Development server
paths:
/weather/current/{city}:
get:
summary: Get current weather for a city
description: Returns the current weather conditions for the specified city
operationId: getCurrentWeather
parameters:
- $ref: '#/components/parameters/CityParam'
- $ref: '#/components/parameters/UnitsParam'
- $ref: '#/components/parameters/LangParam'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/CurrentWeather'
example:
city: London
country: GB
timestamp: "2023-05-15T12:00:00Z"
weather:
temperature: 18.5
feels_like: 17.8
humidity: 65
pressure: 1012
description: "Partly cloudy"
wind:
speed: 12.5
direction: "SW"
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/ServerError'
/weather/forecast/{city}:
get:
summary: Get weather forecast for a city
description: Returns a 5-day weather forecast for the specified city
operationId: getWeatherForecast
parameters:
- $ref: '#/components/parameters/CityParam'
- $ref: '#/components/parameters/UnitsParam'
- $ref: '#/components/parameters/LangParam'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Forecast'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/ServerError'
/weather/history/{city}:
get:
summary: Get historical weather data for a city
description: Returns historical weather data for the specified city
operationId: getWeatherHistory
parameters:
- $ref: '#/components/parameters/CityParam'
- $ref: '#/components/parameters/UnitsParam'
- $ref: '#/components/parameters/LangParam'
- $ref: '#/components/parameters/DaysParam'
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/HistoricalWeather'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/ServerError'
components:
parameters:
CityParam:
name: city
in: path
description: The name of the city to get weather information for
required: true
schema:
type: string
example: "London"
UnitsParam:
name: units
in: query
description: Units of measurement
required: false
schema:
type: string
enum: [metric, imperial]
default: metric
example: "metric"
LangParam:
name: lang
in: query
description: Language for weather descriptions
required: false
schema:
type: string
default: en
example: "en"
DaysParam:
name: days
in: query
description: Number of days for historical data (1-30)
required: false
schema:
type: integer
minimum: 1
maximum: 30
default: 7
example: 7
schemas:
CurrentWeather:
type: object
properties:
city:
type: string
description: City name
country:
type: string
description: Country code
timestamp:
type: string
format: date-time
description: Time of the weather measurement
weather:
$ref: '#/components/schemas/Weather'
required:
- city
- country
- timestamp
- weather
Weather:
type: object
properties:
temperature:
type: number
format: float
description: Temperature in degrees (Celsius or Fahrenheit depending on units parameter)
feels_like:
type: number
format: float
description: Feels like temperature in degrees
humidity:
type: integer
description: Humidity percentage (0-100)
pressure:
type: integer
description: Atmospheric pressure in hPa
description:
type: string
description: Weather condition description
wind:
$ref: '#/components/schemas/Wind'
required:
- temperature
- description
- wind
Wind:
type: object
properties:
speed:
type: number
format: float
description: Wind speed (km/h or mph depending on units parameter)
direction:
type: string
description: Wind direction (N, NE, E, SE, S, SW, W, NW)
required:
- speed
- direction
Forecast:
type: object
properties:
city:
type: string
description: City name
country:
type: string
description: Country code
forecast:
type: array
description: Array of daily forecasts
items:
$ref: '#/components/schemas/DailyForecast'
required:
- city
- country
- forecast
DailyForecast:
type: object
properties:
date:
type: string
format: date
description: Forecast date
weather:
$ref: '#/components/schemas/Weather'
min_temperature:
type: number
format: float
description: Minimum temperature
max_temperature:
type: number
format: float
description: Maximum temperature
precipitation_chance:
type: integer
description: Chance of precipitation (0-100%)
required:
- date
- weather
- min_temperature
- max_temperature
HistoricalWeather:
type: object
properties:
city:
type: string
description: City name
country:
type: string
description: Country code
history:
type: array
description: Array of historical daily weather data
items:
$ref: '#/components/schemas/HistoricalDay'
required:
- city
- country
- history
HistoricalDay:
type: object
properties:
date:
type: string
format: date
description: Date of the historical data
weather:
$ref: '#/components/schemas/Weather'
min_temperature:
type: number
format: float
description: Minimum temperature recorded
max_temperature:
type: number
format: float
description: Maximum temperature recorded
precipitation:
type: number
format: float
description: Total precipitation
required:
- date
- weather
- min_temperature
- max_temperature
responses:
BadRequest:
description: Bad request - invalid parameters provided
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 400
message: "Invalid parameters provided"
NotFound:
description: City not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 404
message: "City not found"
ServerError:
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: 500
message: "Internal server error"
Error:
type: object
properties:
code:
type: integer
description: HTTP status code
message:
type: string
description: Error message
required:
- code
- message
Solution Explanation
This OpenAPI specification includes:
- API Information: Title, description, version, and contact information
- Servers: Production and development server URLs
- Paths: Three endpoints for current weather, forecast, and historical data
- Parameters: Path and query parameters defined as reusable components
- Schemas: Reusable schemas for weather information and response objects
- Responses: Success and error responses with examples
The specification uses component references extensively to promote reusability and maintainability. This approach makes it easier to update the API documentation as the API evolves.