Skip to content

Dependency Injection

The Depends extractor enables automatic dependency resolution for route handlers, supporting database connections, authentication contexts, configuration, and shared services.

Basic Usage

zig
const api = @import("api");

fn getDatabase(ctx: *api.Context) !*Database {
    return ctx.get(*Database, "db") orelse return error.NoDatabaseConnection;
}

fn getCurrentUser(ctx: *api.Context) !User {
    const auth = ctx.header("Authorization") orelse return error.Unauthorized;
    return validateToken(auth);
}

const DbDep = api.extractors.Depends(getDatabase);
const UserDep = api.extractors.Depends(getCurrentUser);

Handler Integration

zig
fn listItems(ctx: *api.Context) api.Response {
    const db = DbDep.extract(ctx) catch {
        return api.Response.err(.internal_server_error, "{\"error\":\"Database unavailable\"}");
    };
    
    const user = UserDep.extract(ctx) catch {
        return api.Response.err(.unauthorized, "{\"error\":\"Authentication required\"}");
    };
    
    const items = db.value.getItemsForUser(user.value.id) catch {
        return api.Response.err(.internal_server_error, "{\"error\":\"Query failed\"}");
    };
    
    return api.Response.jsonFromValue(ctx.allocator, items) catch
        api.Response.err(.internal_server_error, "{}");
}

Dependency Chaining

Dependencies can depend on other dependencies:

zig
fn getAuthenticatedDb(ctx: *api.Context) !AuthenticatedDbConnection {
    const user = try getCurrentUser(ctx);
    const db = try getDatabase(ctx);
    return db.withUser(user);
}

Released under the MIT License.