RealWorld API Versioning Strategy: OpenAPI-Driven Semantic Versioning Without Path Prefixes

The RealWorld API employs OpenAPI-driven semantic versioning without embedding version identifiers in URL paths, declaring version 2.0.0 in the specification file while maintaining version-agnostic /api/ endpoints.

The gothinkster/realworld repository serves as the reference implementation for full-stack application demos, and its RealWorld API versioning strategy deliberately avoids traditional URL path versioning. Instead, the project centralizes version control within the OpenAPI specification, enabling seamless contract evolution without breaking existing endpoint URLs.

OpenAPI-Driven Versioning Without Path Prefixes

Unlike conventional REST APIs that embed version identifiers directly into URL paths (e.g., /api/v1/users), the RealWorld reference implementation keeps all routes version-agnostic. The entire API contract— including the version number— lives in the OpenAPI specification file at specs/api/openapi.yml.

According to the source code, the info.version field at line 11 of specs/api/openapi.yml is set to 2.0.0【/cache/repos/github.com/gothinkster/realworld/main/specs/api/openapi.yml#L11】. This value represents the single source of truth for the API's current version, meaning clients must reference the spec version rather than URL prefixes to determine compatibility.

Semantic Versioning in the Specification

The RealWorld API follows semantic versioning (MAJOR.MINOR.PATCH) as defined in the OpenAPI document:

  • Major version bumps (e.g., 2.0.0 → 3.0.0) indicate breaking changes that require client updates
  • Minor and patch changes (e.g., 2.0.0 → 2.1.0 or 2.0.1) represent backward-compatible additions or bug fixes
  • Because routes never change, existing deployments continue functioning while new clients target updated specs

This approach allows the API contract to evolve independently of the endpoint URLs, ensuring that front-end implementations remain compatible with any back-end that conforms to their targeted spec version.

Version-Agnostic Route Structure

All HTTP routes in the RealWorld API start with the prefix /api/ regardless of the specification version. For example:

  • /api/user returns the current user profile
  • /api/articles lists recent articles
  • /api/profiles/:username retrieves public profile data

The absence of version prefixes (like v1 or v2) means the URL structure remains permanently stable. When the spec advances to 3.0.0, the endpoints stay at /api/..., but the schema contract defined in specs/api/openapi.yml changes to reflect new requirements.

Key Files Defining the Versioning Strategy

Several files in the repository confirm and reinforce this versioning approach:

  • specs/api/openapi.yml: Contains the authoritative info.version: 2.0.0 field and defines the complete API contract
  • specs/api/legacy_Conduit.postman_collection.json: Demonstrates the historical "Conduit" API collection, which also lacks versioned base paths, confirming the long-standing version-agnostic philosophy
  • specs/api/README.md: Provides guidance for consumers on referencing the OpenAPI spec and understanding versioning semantics
  • README.md (repo root): States that front-ends can be swapped between back-ends because all implementations share the same API spec, reinforcing that versioning is tied to the specification document rather than deployment URLs

Programmatically Detecting API Versions

Because the version lives in the YAML specification rather than the URL, clients must query the spec file directly to determine the current API contract version.

Fetching the Current Spec Version

Use the raw GitHub URL to retrieve the OpenAPI file and parse the version line:

import fetch from 'node-fetch';

async function getSpecVersion() {
  const resp = await fetch(
    'https://raw.githubusercontent.com/gothinkster/realworld/main/specs/api/openapi.yml'
  );
  const text = await resp.text();
  const versionLine = text.split('\n').find(l => l.trim().startsWith('version:'));
  console.log('API spec version →', versionLine.split(':')[1].trim());
}

getSpecVersion(); // prints “2.0.0”

Calling Version-Agnostic Endpoints

Client requests never include version prefixes, regardless of which spec version the server implements:

async function getCurrentUser(token) {
  const resp = await fetch('https://api.realworld.show/api/user', {
    headers: { Authorization: `Token ${token}` },
  });
  return resp.json(); // conforms to the schema described in the 2.0.0 spec
}

Preparing for Major Version Updates

When the maintainers release a breaking change (hypothetical 3.0.0), update your client code to validate against the new schema while keeping the same base URL:

// When the spec is bumped to 3.0.0, update the import URL:
const SPEC_URL = 'https://raw.githubusercontent.com/gothinkster/realworld/main/specs/api/openapi.yml';
// After the bump, SPEC_URL will return a file whose `version:` line reads “3.0.0”.

Summary

  • The RealWorld API uses OpenAPI-driven semantic versioning without URL path prefixes, making specs/api/openapi.yml the single source of truth
  • Current version 2.0.0 follows MAJOR.MINOR.PATCH semantics, where breaking changes trigger major version increments
  • All endpoints remain version-agnostic under /api/, requiring clients to track specification versions independently of deployment URLs
  • The legacy_Conduit.postman_collection.json and root README.md confirm that the versioning strategy prioritizes specification consistency over URL structure changes

Frequently Asked Questions

Does the RealWorld API use URL path versioning like /api/v1/?

No. According to the source code in specs/api/openapi.yml, the RealWorld API intentionally avoids embedding version identifiers in URL paths. All routes start with /api/ regardless of the specification version, making the strategy "OpenAPI-driven semantic versioning without path versioning."

What is the current RealWorld API version?

The OpenAPI specification at specs/api/openapi.yml declares version 2.0.0 in the info.version field. This follows semantic versioning conventions where breaking changes would increment the major version to 3.0.0, while backward-compatible additions only modify the minor or patch components.

How should client applications handle RealWorld API version changes?

Clients should reference the specific OpenAPI spec version they were built against. When the spec advances to a new major version (e.g., 3.0.0), developers must update their client libraries or front-end code to match the new schema, while existing deployments continue functioning against the same /api/ endpoints.

Where is the RealWorld API version defined in the codebase?

The single source of truth resides in specs/api/openapi.yml at the info.version field. The specs/api/legacy_Conduit.postman_collection.json file and root README.md further confirm that the API contract is versioned through the specification document rather than URL paths.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →