openapi2zig

Generate type-safe Zig client code from OpenAPI specifications

A CLI tool written in Zig that generates API client code in Zig from OpenAPI specifications. Parse OpenAPI v3.0 specifications and generate idiomatic, type-safe Zig client code for your APIs. Swagger v2.0 support coming soon!

CI Status Zig Version License

Installation

This tool is distributed as a compiled binary for multiple platforms.

Quick Install Script (Recommended)

The easiest way to install openapi2zig on your system.

Bash
curl -fsSL https://christianhelle.com/openapi2zig/install | bash
PowerShell
irm https://christianhelle.com/openapi2zig/install.ps1 | iex

Manual Download

Download the latest release for your platform:

  • Linux x86_64: openapi2zig-linux-x86_64.tar.gz
  • macOS x86_64: openapi2zig-macos-x86_64.tar.gz
  • macOS ARM64: openapi2zig-macos-aarch64.tar.gz
  • Windows x86_64: openapi2zig-windows-x86_64.zip
Download Latest Release

Install from Snap Store

Install the latest build for Linux from the Snap Store:

Bash
snap install --edge openapi2zig

Build from Source

For developers who want to build from source:

Build Commands
git clone https://github.com/christianhelle/openapi2zig.git
cd openapi2zig
zig build

Development Environment

Get started with contributing to openapi2zig quickly using our pre-configured development environments.

🐳 VS Code Dev Containers (Local)

If you prefer local development with Docker, use our dev container configuration for a consistent development environment.

  1. Install VS Code and the Dev Containers extension
  2. Clone the repository and open it in VS Code
  3. When prompted, click "Reopen in Container"
  4. VS Code will build and configure the development environment automatically

⚙️ Manual Setup

For traditional local development, install Zig following the official installation guide.

Prerequisites: Zig v0.14.1 or later

Development Workflow

Once your development environment is ready:

Build the project:

Shell
zig build

Run tests:

Shell
zig build test

Run the application:

Shell
zig build run

Usage

Note: The CLI interface is currently under development. The tool currently includes OpenAPI parsing functionality and will be extended with code generation capabilities.

Command-line Interface

Shell
openapi2zig generate [options]

Options

Flag Description
-i, --input <path> Path to the OpenAPI Specification file (JSON or YAML).
-o, --output <path> Path to the output directory for the generated Zig code (default: current directory).
--base-url <url> Base URL for the API client (default: server URL from OpenAPI Specification).

Current Capabilities

  • ✅ OpenAPI v3.0 specification parsing
  • 🔜 Swagger v2.0 specification parsing (coming soon)
  • ✅ Basic data model structures for OpenAPI components
  • ✅ Comprehensive test suite for parsing functionality
  • 🚧 CLI interface for code generation
  • 🚧 Zig client code generation
  • 🚧 Support for authentication and complex schemas

Example Generated Code

Below is an example of the Zig code generated from an OpenAPI specification.

Models

Zig
///////////////////////////////////////////
// Generated Zig structures from OpenAPI
///////////////////////////////////////////

pub const Order = struct {
    status: ?[]const u8 = null,
    petId: ?i64 = null,
    complete: ?bool = null,
    id: ?i64 = null,
    quantity: ?i64 = null,
    shipDate: ?[]const u8 = null,
}

pub const Pet = struct {
    status: ?[]const u8 = null,
    tags: ?[]const u8 = null,
    category: ?[]const u8 = null,
    id: ?i64 = null,
    name: []const u8,
    photoUrls: []const u8,
};

API Client

Zig
///////////////////////////////////////////
// Generated Zig API client from OpenAPI
///////////////////////////////////////////

const std = @import("std");

/////////////////
// Summary:
// Place an order for a pet
//
// Description:
// Place a new order in the store
//
pub fn placeOrder(allocator: std.mem.Allocator, requestBody: Order) !void {
    // Avoid warnings about unused parameters
    _ = requestBody;

    var client = std.http.Client.init(allocator);
    defer client.deinit();

    const uri = try std.Uri.parse("/store/order");
    const buf = try allocator.alloc(u8, 1024 * 8);
    defer allocator.free(buf);   var req = try client.open(.POST, uri, .{
        .server_header_buffer = buf,
    });
    defer req.deinit();

    // TODO: Set request body and headers

    try req.send();
    try req.finish();
    try req.wait();
}

/////////////////
// Summary:
// Add a new pet to the store
//
// Description:
// Add a new pet to the store
//
pub fn addPet(allocator: std.mem.Allocator, requestBody: Pet) !void {
    var client = std.http.Client.init(allocator);
    defer client.deinit();

    const uri = try std.Uri.parse('''https://petstore.swagger.io/api/v3/pet''');
    const buf = try allocator.alloc(u8, 1024 * 8);
    defer allocator.free(buf);

    var req = try client.open(.POST, uri, .{
        .server_header_buffer = buf,
    });
    defer req.deinit();

    try req.send();

    var str = std.ArrayList(u8).init(allocator);
    defer str.deinit();

    try std.json.stringify(requestBody, .{}, str.writer());
    const body = try std.mem.join(allocator, '''''', str.items);

    req.transfer_encoding = .{ .content_length = body.len };
    try req.writeAll(body);

    try req.finish();
    try req.wait();
}

Contributing

We welcome contributions to openapi2zig! Here's how you can help:

1

Fork the Repository

Create your own fork of the openapi2zig repository on GitHub.

2

Create a Feature Branch

Create a new branch for your feature or bug fix.

git checkout -b feature/amazing-feature
3

Make Your Changes

Implement your feature or fix, ensuring you follow the coding standards.

4

Test Your Changes

Run the test suite and ensure all tests pass.

zig build test
5

Submit a Pull Request

Push your changes and create a pull request for review.

Code Style

This project follows standard Zig formatting. Use zig fmt to format your code before committing.

Format Check
zig fmt --check src/
zig fmt --check build.zig