Skip to content
43 changes: 40 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,9 @@ const createItem = create("/item", {

### Open API

Better Call by default generate open api schema for the endpoints and exposes it on `/api/reference` path using scalar. By default, if you're using `zod` it'll be able to generate `body` and `query` schema.
Better Call by default generates an OpenAPI schema for the endpoints and exposes it on the `/api/reference` path using scalar. `body` and `query` schemas are generated automatically for any schema library that implements the [Standard JSON Schema](https://standardschema.dev/json-schema) interface (Zod `>= 4.2`, ArkType `>= 2.1.28`, and others); libraries without it fall back to a generic object schema and can be described explicitly via `metadata.openapi` (see below).

Every method of an endpoint — including `PUT`, `PATCH`, and `DELETE`, and multiple methods on the same path — is documented, and `:param` route segments are rendered as OpenAPI `{param}` path parameters.

```ts
import { createEndpoint, createRouter } from "better-call"
Expand Down Expand Up @@ -837,9 +839,32 @@ const createItem = createEndpoint("/item/:id", {
})
```

#### Authentication

Better Call is auth-agnostic and does **not** assert any security scheme by default. To document authentication in an OpenAPI-standard way, declare your security schemes and a document-level requirement on the router. Per-endpoint requirements can be set via `metadata.openapi.security` and override the document-level default for that operation.

```ts
const router = createRouter({
createItem
}, {
openapi: {
// Exposed under components.securitySchemes
securitySchemes: {
sessionCookie: {
type: "apiKey",
in: "cookie",
name: "better-auth.session_token"
}
},
// Applied to every operation unless overridden per-endpoint
security: [{ sessionCookie: [] }]
}
})
```

#### Configuration

You can configure the open api schema by passing the `openapi` option to the router.
You can configure the OpenAPI schema by passing the `openapi` option to the router.

```ts
const router = createRouter({
Expand All @@ -848,9 +873,21 @@ const router = createRouter({
openapi: {
disabled: false, //default false
path: "/api/reference", //default /api/reference
scalar: {
// OpenAPI Info Object (defaults to { title: "API Reference", version: "1.0.0" })
info: {
title: "My API",
version: "1.0.0",
description: "My API Description"
},
// OpenAPI Server Objects
servers: [{ url: "https://api.example.com" }],
// See "Authentication" above
security: [{ sessionCookie: [] }],
securitySchemes: {
sessionCookie: { type: "apiKey", in: "cookie", name: "better-auth.session_token" }
},
scalar: {
title: "My API",
description: "My API Description",
theme: "dark" //default saturn
}
Expand Down
12 changes: 11 additions & 1 deletion packages/better-call/src/endpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import {
} from "./error";
import type { HasRequiredKeys, Prettify } from "./helper";
import type { Middleware } from "./middleware";
import type { OpenAPIParameter, OpenAPISchemaType } from "./openapi";
import type {
OpenAPIParameter,
OpenAPISchemaType,
OpenAPISecurityRequirement,
} from "./openapi";
import type { StandardSchemaV1 } from "./standard-schema";
import { toResponse } from "./to-response";
import type {
Expand All @@ -36,6 +40,12 @@ export interface EndpointMetadata {
description?: string;
tags?: string[];
operationId?: string;
/**
* Security requirements for this operation. Overrides the document-level
* `security` when set. Each entry maps a security scheme name (declared in
* `components.securitySchemes`) to its required scopes.
*/
security?: OpenAPISecurityRequirement[];
parameters?: OpenAPIParameter[];
requestBody?: {
content: {
Expand Down
18 changes: 12 additions & 6 deletions packages/better-call/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ export type { Prettify } from "./helper";
export type { Middleware, MiddlewareContext } from "./middleware";
// Middleware
export { createMiddleware } from "./middleware";
export type { OpenAPIParameter, OpenAPISchemaType } from "./openapi";
export type {
OpenAPIGeneratorConfig,
OpenAPIParameter,
OpenAPISchemaType,
OpenAPISecurityRequirement,
OpenAPISecurityScheme,
} from "./openapi";

// OpenAPI
export {
Expand All @@ -33,6 +39,11 @@ export {
export type { Router, RouterConfig } from "./router";
// Router
export { createRouter } from "./router";
// Schema
export type { StandardSchemaV1 } from "./standard-schema";
export type { JSONResponse } from "./to-response";
// Response
export { toResponse } from "./to-response";
// Types
export type {
HTTPMethod,
Expand All @@ -42,8 +53,3 @@ export type {
ResolveMetaInput,
ResolveQueryInput,
} from "./types";
// Schema
export type { StandardSchemaV1 } from "./standard-schema";
export type { JSONResponse } from "./to-response";
// Response
export { toResponse } from "./to-response";
Loading