Home > Practice Exercises > Basic OpenAPI Specification

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.

Exercise Objectives
  • 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
Tip

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:

  1. Create a YAML file containing your OpenAPI specification
  2. Validate your specification using the Swagger Editor or another OpenAPI validator
  3. Save the file as weather-api.yaml
  4. 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:

key">openapi: 3.0.3
key">info:
  key">title: Weather API
  key">description: |
    A simple API for retrieving weather information for cities around the world.
    This API provides current weather conditions, forecasts, and historical data.
  key">version: 1.0.0
  key">contact:
    key">name: API Support
    key">email: support@weatherapi.example.com
    key">url: key">https://www.weatherapi.example.com/support
  
key">servers:
  - key">url: key">https://api.weatherapi.example.com/v1
    key">description: Production server
  - key">url: key">https://dev.weatherapi.example.com/v1
    key">description: Development server

key">paths:
  /weather/current/{city}:
    key">get:
      key">summary: Get current weather for a city
      key">description: Returns the current weather conditions for the specified city
      key">operationId: getCurrentWeather
      key">parameters:
        - $key">ref: '#/components/parameters/CityParam'
        - $key">ref: '#/components/parameters/UnitsParam'
        - $key">ref: '#/components/parameters/LangParam'
      key">responses:
        '200':
          key">description: Successful operation
          key">content:
            application/key">json:
              key">schema:
                $key">ref: '#/components/schemas/CurrentWeather'
              key">example:
                key">city: London
                key">country: GB
                key">timestamp: ""key">2023-05-15T12:"key">00:00Z"
                key">weather:
                  key">temperature: 18.5
                  key">feels_like: 17.8
                  key">humidity: 65
                  key">pressure: 1012
                  key">description: "Partly cloudy"
                  key">wind:
                    key">speed: 12.5
                    key">direction: "SW"
        '400':
          $key">ref: '#/components/responses/BadRequest'
        '404':
          $key">ref: '#/components/responses/NotFound'
        '500':
          $key">ref: '#/components/responses/ServerError'
  
  /weather/forecast/{city}:
    key">get:
      key">summary: Get weather forecast for a city
      key">description: Returns a 5-day weather forecast for the specified city
      key">operationId: getWeatherForecast
      key">parameters:
        - $key">ref: '#/components/parameters/CityParam'
        - $key">ref: '#/components/parameters/UnitsParam'
        - $key">ref: '#/components/parameters/LangParam'
      key">responses:
        '200':
          key">description: Successful operation
          key">content:
            application/key">json:
              key">schema:
                $key">ref: '#/components/schemas/Forecast'
        '400':
          $key">ref: '#/components/responses/BadRequest'
        '404':
          $key">ref: '#/components/responses/NotFound'
        '500':
          $key">ref: '#/components/responses/ServerError'
  
  /weather/history/{city}:
    key">get:
      key">summary: Get historical weather data for a city
      key">description: Returns historical weather data for the specified city
      key">operationId: getWeatherHistory
      key">parameters:
        - $key">ref: '#/components/parameters/CityParam'
        - $key">ref: '#/components/parameters/UnitsParam'
        - $key">ref: '#/components/parameters/LangParam'
        - $key">ref: '#/components/parameters/DaysParam'
      key">responses:
        '200':
          key">description: Successful operation
          key">content:
            application/key">json:
              key">schema:
                $key">ref: '#/components/schemas/HistoricalWeather'
        '400':
          $key">ref: '#/components/responses/BadRequest'
        '404':
          $key">ref: '#/components/responses/NotFound'
        '500':
          $key">ref: '#/components/responses/ServerError'

key">components:
  key">parameters:
    key">CityParam:
      key">name: city
      key">in: path
      key">description: The name of the city to get weather information for
      key">required: true
      key">schema:
        key">type: string
      key">example: "London"
      
    key">UnitsParam:
      key">name: units
      key">in: query
      key">description: Units of measurement
      key">required: false
      key">schema:
        key">type: string
        key">enum: [metric, imperial]
        key">default: metric
      key">example: "metric"
      
    key">LangParam:
      key">name: lang
      key">in: query
      key">description: Language for weather descriptions
      key">required: false
      key">schema:
        key">type: string
        key">default: en
      key">example: "en"
      
    key">DaysParam:
      key">name: days
      key">in: query
      key">description: Number of days for historical data (1-30)
      key">required: false
      key">schema:
        key">type: integer
        key">minimum: 1
        key">maximum: 30
        key">default: 7
      key">example: 7
  
  key">schemas:
    key">CurrentWeather:
      key">type: object
      key">properties:
        key">city:
          key">type: string
          key">description: City name
        key">country:
          key">type: string
          key">description: Country code
        key">timestamp:
          key">type: string
          key">format: date-time
          key">description: Time of the weather measurement
        key">weather:
          $key">ref: '#/components/schemas/Weather'
      key">required:
        - city
        - country
        - timestamp
        - weather
          
    key">Weather:
      key">type: object
      key">properties:
        key">temperature:
          key">type: number
          key">format: float
          key">description: Temperature in degrees (Celsius or Fahrenheit depending on units parameter)
        key">feels_like:
          key">type: number
          key">format: float
          key">description: Feels like temperature in degrees
        key">humidity:
          key">type: integer
          key">description: Humidity percentage (0-100)
        key">pressure:
          key">type: integer
          key">description: Atmospheric pressure in hPa
        key">description:
          key">type: string
          key">description: Weather condition description
        key">wind:
          $key">ref: '#/components/schemas/Wind'
      key">required:
        - temperature
        - description
        - wind
            
    key">Wind:
      key">type: object
      key">properties:
        key">speed:
          key">type: number
          key">format: float
          key">description: Wind speed (km/h or mph depending on units parameter)
        key">direction:
          key">type: string
          key">description: Wind direction (N, NE, E, SE, S, SW, W, NW)
      key">required:
        - speed
        - direction
            
    key">Forecast:
      key">type: object
      key">properties:
        key">city:
          key">type: string
          key">description: City name
        key">country:
          key">type: string
          key">description: Country code
        key">forecast:
          key">type: array
          key">description: Array of daily forecasts
          key">items:
            $key">ref: '#/components/schemas/DailyForecast'
      key">required:
        - city
        - country
        - forecast
            
    key">DailyForecast:
      key">type: object
      key">properties:
        key">date:
          key">type: string
          key">format: date
          key">description: Forecast date
        key">weather:
          $key">ref: '#/components/schemas/Weather'
        key">min_temperature:
          key">type: number
          key">format: float
          key">description: Minimum temperature
        key">max_temperature:
          key">type: number
          key">format: float
          key">description: Maximum temperature
        key">precipitation_chance:
          key">type: integer
          key">description: Chance of precipitation (0-100%)
      key">required:
        - date
        - weather
        - min_temperature
        - max_temperature
            
    key">HistoricalWeather:
      key">type: object
      key">properties:
        key">city:
          key">type: string
          key">description: City name
        key">country:
          key">type: string
          key">description: Country code
        key">history:
          key">type: array
          key">description: Array of historical daily weather data
          key">items:
            $key">ref: '#/components/schemas/HistoricalDay'
      key">required:
        - city
        - country
        - history
            
    key">HistoricalDay:
      key">type: object
      key">properties:
        key">date:
          key">type: string
          key">format: date
          key">description: Date of the historical data
        key">weather:
          $key">ref: '#/components/schemas/Weather'
        key">min_temperature:
          key">type: number
          key">format: float
          key">description: Minimum temperature recorded
        key">max_temperature:
          key">type: number
          key">format: float
          key">description: Maximum temperature recorded
        key">precipitation:
          key">type: number
          key">format: float
          key">description: Total precipitation
      key">required:
        - date
        - weather
        - min_temperature
        - max_temperature
  
  key">responses:
    key">BadRequest:
      key">description: Bad request - invalid parameters provided
      key">content:
        application/key">json:
          key">schema:
            $key">ref: '#/components/schemas/Error'
          key">example:
            key">code: 400
            key">message: "Invalid parameters provided"
            
    key">NotFound:
      key">description: City not found
      key">content:
        application/key">json:
          key">schema:
            $key">ref: '#/components/schemas/Error'
          key">example:
            key">code: 404
            key">message: "City not found"
            
    key">ServerError:
      key">description: Internal server error
      key">content:
        application/key">json:
          key">schema:
            $key">ref: '#/components/schemas/Error'
          key">example:
            key">code: 500
            key">message: "Internal server error"
            
    key">Error:
      key">type: object
      key">properties:
        key">code:
          key">type: integer
          key">description: HTTP status code
        key">message:
          key">type: string
          key">description: Error message
      key">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.