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:

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.