Skip to content

api‐zimic‐http‐schemas

github-actions[bot] edited this page Mar 3, 2025 · 1 revision

zimic/http - API reference schemas

Contents


HTTP schemas define the structure of the real services being mocked. This includes paths, methods, request and response bodies, and status codes. @zimic/fetch and @zimic/interceptor use such schemas to type requests and responses.

Tip

If you are using TypeScript and have an OpenAPI v3 schema, you can use zimic-http typegen to automatically generate types for your schema!

An example of a complete HTTP schema:
import { type HttpSchema } from '@zimic/http';

// Declaring base types
interface User {
  username: string;
}

interface UserCreationBody {
  username: string;
}

interface NotFoundError {
  message: string;
}

interface UserCreationResponseHeaders {
  'content-type': string;
}

interface UserListSearchParams {
  name?: string;
  orderBy?: `${'name' | 'email'}.${'asc' | 'desc'}`[];
}

// Declaring the schema
type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      request: {
        headers: { accept: string };
        body: UserCreationBody;
      };
      response: {
        201: {
          headers: UserCreationResponseHeaders;
          body: User;
        };
      };
    };
    GET: {
      request: {
        searchParams: UserListSearchParams;
      };
      response: {
        200: { body: User[] };
        404: { body: NotFoundError };
      };
    };
  };

  '/users/:id': {
    GET: {
      response: {
        200: { body: User };
        404: { body: NotFoundError };
      };
    };
  };
}>;
Alternatively, you can compose the schema using utility types:
import { type HttpSchema } from '@zimic/http';

// Declaring the base types
interface User {
  username: string;
}

interface UserCreationBody {
  username: string;
}

interface NotFoundError {
  message: string;
}

interface UserCreationResponseHeaders {
  'content-type': string;
}

interface UserListSearchParams {
  name?: string;
  orderBy?: `${'name' | 'email'}.${'asc' | 'desc'}`[];
}

// Declaring user methods
type UserMethods = HttpSchema.Methods<{
  POST: {
    request: {
      headers: { accept: string };
      body: UserCreationBody;
    };
    response: {
      201: {
        headers: UserCreationResponseHeaders;
        body: User;
      };
    };
  };

  GET: {
    request: {
      searchParams: UserListSearchParams;
    };
    response: {
      200: { body: User[] };
      404: { body: NotFoundError };
    };
  };
}>;

type UserByIdMethods = HttpSchema.Methods<{
  GET: {
    response: {
      200: { body: User };
      404: { body: NotFoundError };
    };
  };
}>;

// Declaring user paths
type UserPaths = HttpSchema<{
  '/users': UserMethods;
}>;

type UserByIdPaths = HttpSchema<{
  '/users/:id': UserByIdMethods;
}>;

// Declaring the schema
type MyServiceSchema = UserPaths & UserByIdPaths;

Declaring HTTP paths

At the root level, each key represents a path or route of the service:

import { type HttpSchema } from '@zimic/http';

type MyServiceSchema = HttpSchema<{
  '/users': {
    // Path schema
  };
  '/users/:id': {
    // Path schema
  };
  '/posts': {
    // Path schema
  };
}>;
Alternatively, you can also compose paths using HttpSchema:
import { type HttpSchema } from '@zimic/http';

type UserPaths = HttpSchema<{
  '/users': {
    // Path schema
  };
  '/users/:id': {
    // Path schema
  };
}>;

type PostPaths = HttpSchema<{
  '/posts': {
    // Path schema
  };
}>;

Declaring HTTP methods

Each path can have one or more methods, (GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS). The method names are case-sensitive.

import { type HttpSchema } from '@zimic/http';

type MyServiceSchema = HttpSchema<{
  '/users': {
    GET: {
      // Method schema
    };
    POST: {
      // Method schema
    };
  };
  // Other paths
}>;
You can also compose methods using HttpSchema.Methods:
import { type HttpSchema } from '@zimic/http';

type UserMethods = HttpSchema.Methods<{
  GET: {
    // Method schema
  };
  POST: {
    // Method schema
  };
}>;

Declaring HTTP requests

Each method can have a request, which defines the schema of the accepted requests. headers, searchParams, and body are supported to provide type safety when applying mocks. Path parameters are automatically inferred from the path string, such as /users/:id.

Declaring a request type with search params:
import { type HttpSchema } from '@zimic/http';

interface UserListSearchParams {
  query?: string;
}

type MyServiceSchema = HttpSchema<{
  '/users': {
    GET: {
      request: { searchParams: UserListSearchParams };
    };
  };
}>;
Declaring a request type with a JSON body:
import { type HttpSchema } from '@zimic/http';

interface UserCreationBody {
  username: string;
}

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      request: { body: UserCreationBody };
    };
  };
}>;

Tip

The utility type JSONValue is useful to check if your types are compatible with JSON.

Tip

The utility type JSONSerialized is handy to infer the serialized type of an object. It converts Date's to strings, removes function properties and serializes nested objects and arrays.

Declaring a request type with a form data body:
import { type HttpSchema, type HttpFormData } from '@zimic/http';

type FileUploadData = HttpSchema.FormData<{
  files: File[];
  description?: string;
}>;

type MyServiceSchema = HttpSchema<{
  '/files': {
    POST: {
      request: { body: HttpFormData<FileUploadData> };
    };
  };
}>;
Declaring a request type with a blob body:
import { type HttpSchema } from '@zimic/http';

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      request: { body: Blob };
    };
  };
}>;
Declaring a request type with a plain text body:
import { type HttpSchema } from '@zimic/http';

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      request: { body: string };
    };
  };
}>;
Declaring a request type with a search params (x-www-form-urlencoded) body:
import { type HttpSchema, type HttpSearchParams } from '@zimic/http';

type UserListSearchParams = HttpSchema.SearchParams<{
  query?: string;
}>;

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      request: { body: HttpSearchParams<UserListSearchParams> };
    };
  };
}>;
You can also compose requests using HttpSchema.Request:
import { type HttpSchema } from '@zimic/http';

interface UserCreationBody {
  username: string;
}

type UserCreationRequest = HttpSchema.Request<{
  body: UserCreationBody;
}>;

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      request: UserCreationRequest;
    };
  };
}>;

Declaring HTTP responses

Each method can also have a response, which defines the schema of the returned responses. The status codes are used as keys. headers and body are supported to provide type safety when applying mocks.

Bodies can be a JSON object, HttpFormData, HttpSearchParams, Blob, or plain text.

Declaring a response type with a JSON body:
interface User {
  username: string;
}

interface NotFoundError {
  message: string;
}

type MyServiceSchema = HttpSchema<{
  '/users/:id': {
    GET: {
      response: {
        200: { body: User };
        404: { body: NotFoundError };
      };
    };
  };
}>;

Tip

The utility type JSONValue is useful to check if your types are compatible with JSON.

Tip

The utility type JSONSerialized is handy to infer the serialized type of an object. It converts Date's to strings, removes function properties and serializes nested objects and arrays.

Declaring a response type with a form data body:
import { type HttpSchema, type HttpFormData } from '@zimic/http';

type FileUploadData = HttpSchema.FormData<{
  files: File[];
  description?: string;
}>;

type MyServiceSchema = HttpSchema<{
  '/files': {
    POST: {
      response: {
        200: { body: HttpFormData<FileUploadData> };
      };
    };
  };
}>;
Declaring a response type with a blob body:
import { type HttpSchema } from '@zimic/http';

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      response: {
        200: { body: Blob };
      };
    };
  };
}>;
Declaring a response type with a plain text body:
import { type HttpSchema } from '@zimic/http';

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      response: {
        200: { body: string };
      };
    };
  };
}>;
Declaring a response type with a search params (x-www-form-urlencoded) body:
import { type HttpSchema, type HttpSearchParams } from '@zimic/http';

type UserListSearchParams = HttpSchema.SearchParams<{
  query?: string;
}>;

type MyServiceSchema = HttpSchema<{
  '/users': {
    POST: {
      response: {
        200: { body: HttpSearchParams<UserListSearchParams> };
      };
    };
  };
}>;
You can also compose responses using HttpSchema.ResponseByStatusCode and HttpSchema.Response:
import { type HttpSchema } from '@zimic/http';

interface User {
  username: string;
}

interface NotFoundError {
  message: string;
}

type SuccessUserGetResponse = HttpSchema.Response<{
  body: User;
}>;

type NotFoundUserGetResponse = HttpSchema.Response<{
  body: NotFoundError;
}>;

type UserGetResponses = HttpSchema.ResponseByStatusCode<{
  200: SuccessUserGetResponse;
  404: NotFoundUserGetResponse;
}>;

type MyServiceSchema = HttpSchema<{
  '/users/:id': {
    GET: {
      response: UserGetResponses;
    };
  };
}>;