High Performance
Zero runtime reflection with compile-time route validation for maximum speed
Build blazing-fast APIs with compile-time safety, multi-threaded concurrency, GraphQL, WebSocket, and production-ready features
Install api.zig:
zig fetch --save https://github.com/muhammad-fiaz/api.zig/archive/refs/heads/main.tar.gzAdd to build.zig:
const api_dep = b.dependency("api", .{ .target = target, .optimize = optimize });
exe.root_module.addImport("api", api_dep.module("api"));Create your first API:
const std = @import("std");
const api = @import("api");
fn hello() api.Response {
return api.Response.jsonRaw("{\"message\":\"Hello, World!\"}");
}
fn getUser(ctx: *api.Context) api.Response {
const id = ctx.param("id") orelse "0";
_ = id;
return api.Response.jsonRaw("{\"id\":1,\"name\":\"John\"}");
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
var app = try api.App.init(allocator, .{
.title = "My API",
.version = "1.0.0",
});
defer app.deinit();
try app.get("/", hello);
try app.get("/users/{id}", getUser);
try app.run(.{ .port = 8000, .num_threads = 4 });
}Run your server:
zig build runVisit:
// Single-threaded (num_threads = 0)
try app.run(.{ .port = 8000 });
// Multi-threaded with 4 workers
try app.run(.{ .port = 8000, .num_threads = 4 });
// Auto-detect based on CPU count
try app.run(.{ .port = 8000, .num_threads = null });// Enable access logging (default)
try app.run(.{ .port = 8000, .access_log = true });
// Disable access logging
try app.run(.{ .port = 8000, .access_log = false });api.Response.jsonRaw("{\"key\":\"value\"}") // JSON
api.Response.text("Hello") // Plain text
api.Response.html("<h1>Hello</h1>") // HTML
api.Response.redirect("/new-path") // Redirect (302)
api.Response.permanentRedirect("/new") // Redirect (301)
api.Response.err(.not_found, "{}") // Error responsetry app.get("/users/{id}", getUser);
try app.get("/posts/{post_id}/comments/{comment_id}", getComment);fn listUsers(ctx: *api.Context) api.Response {
const page = ctx.queryAsOr(u32, "page", 1);
const limit = ctx.queryAsOr(u32, "limit", 10);
// ...
}api.Response.text("Created")
.setStatus(.created)
.setHeader("Location", "/users/1")
.setHeader("X-Request-Id", "abc123")
.withCors("*");var client = api.Client.init(allocator);
defer client.deinit();
const response = try client.get("https://api.example.com/data");
defer response.deinit();
const data = try response.json(MyType);const static_handler = api.StaticFiles.serve(.{
.root_path = "public",
.url_prefix = "/static",
});
try app.mount("/static", static_handler);const templates = api.Templates.init(allocator, "templates");
return templates.render("index.html", .{
.title = "Home",
.user = username,
});var app = try api.App.init(allocator, .{});
// Define schema
var schema = api.graphql.Schema.init(allocator);
try schema.setQueryType(.{
.name = "Query",
.fields = &.{
.{ .name = "users", .type_name = "User", .is_list = true },
},
});
// Enable GraphQL
try app.enableGraphQL(&schema);
// Endpoints: POST /graphql, GET /graphql (GraphiQL)try app.enableWebSocket(.{
.max_connections = 10000,
.ping_interval_ms = 30000,
});
app.router.get("/ws", fn(ctx: *api.Context) !void {
try ctx.response.upgradeWebSocket(.{
.on_message = onMessage,
.on_close = onClose,
});
});try app.enableMetrics(.{ .prefix = "myapp" });
try app.enableHealthChecks();
// GET /metrics -> Prometheus format
// GET /health -> Health check endpointtry app.enableCaching(.{
.max_entries = 5000,
.default_ttl_seconds = 300,
});try app.enableSessions(.{
.secret = "your-secret-key-at-least-32-chars",
.max_age_seconds = 86400,
});| Field | Type | Default | Description |
|---|---|---|---|
title | []const u8 | "Zig API Framework" | API title for OpenAPI |
version | []const u8 | "1.0.0" | API version |
description | ?[]const u8 | null | API description |
debug | bool | false | Enable debug mode |
docs_url | []const u8 | "/docs" | Swagger UI path |
redoc_url | []const u8 | "/redoc" | ReDoc path |
openapi_url | []const u8 | "/openapi.json" | OpenAPI spec path |
| Field | Type | Default | Description |
|---|---|---|---|
host | []const u8 | "127.0.0.1" | Bind address |
port | u16 | 8000 | Listen port |
access_log | bool | true | Enable/disable access logging |
num_threads | ?u8 | null | Worker threads (null=auto, 0=single) |
auto_port | bool | true | Auto-find port if busy |
api.zig provides api.Defaults for production-ready configurations:
// Use production defaults
const server_config = api.Defaults.server;
const cors_config = api.Defaults.cors;
const rate_limit_config = api.Defaults.rateLimit;
const security_config = api.Defaults.security;Use api.FrameworkConfig for unified configuration:
const config = api.FrameworkConfig{
.app = .{ .title = "My API" },
.server = .{ .port = 8080, .num_threads = 4 },
.cors = .{ .allowed_origins = &.{"https://example.com"} },
.rate_limit = .{ .requests_per_window = 100 },
.security = .{ .x_frame_options = .deny },
.graphql = .{ .enable_introspection = true },
.metrics = .{ .prefix = "myapp" },
.session = .{ .secret = "your-secret-key" },
};// Recommended middleware order
try app.use(api.recover); // Catch panics
try app.use(api.requestId); // Request tracing
try app.use(api.logger); // Access logging
try app.use(api.defaultSecurityHeaders); // Security headers
try app.use(api.cors(.{}).handle); // CORS
try app.use(api.rateLimit(.{}).handle); // Rate limiting