@api-ts/io-ts-http

中文文档
3.2.4发布于 2026/08/05Apache-2.0TypeScriptCommonJS构建来源已验证近 30 天下载 17.2万

Types for (de)serializing HTTP requests from both the client and server side

原始使用文档
文档目录9 节
  1. Contents
  2. Preface
  3. Introduction
  4. Overview
  5. Example
  6. apiSpec
  7. httpRoute
  8. httpRequest
  9. Documentation

@api-ts/io-ts-http

Runtime types for (de)serializing HTTP requests from both the client and server side

Contents

Preface

This package extends io-ts with functionality useful for typing HTTP requests. Start there for base knowledge required to use this package.

Introduction

io-ts-http is the definition language for api-ts specifications, which define the API contract for a web sever to an arbitrary degree of precision. Web servers can use the io-ts-http spec to parse HTTP requests at runtime, and encode HTTP responses. Clients can use the io-ts-http spec to enforce API compatibility at compile time, and to encode requests to the server and decode responses.

Overview

The primary function in this library is httpRequest. You can use this to build codecs which can parse a generic HTTP request into a more refined type. The generic HTTP request should conform to the following interface:

interface GenericHttpRequest {
  params: {
    [K: string]: string;
  };
  query: {
    [K: string]: string | string[];
  };
  headers: {
    [K: string]: string;
  };
  body?: unknown;
}

Here, params represents the path parameters and query is minimally-parsed query string parameters (basically just the results of splitting up the query string and urlDecoding the values). The httpRequest function can be combined with codecs from io-ts to build a combined codec that is able to validate, parse, and encode these generic HTTP requests into a more refined object. For example:

import { httpRequest, optional } from '@api-ts/io-ts-http';
import { DateFromISOString, NumberFromString } from 'io-ts-types';

const ExampleHttpRequest = httpRequest({
  query: {
    id: NumberFromString,
    time: optional(DateFromISOString),
  },
});

This builds a codec that can be given an arbitrary HTTP request and will ensure that it contains an id parameter, and also optionally will check for a time parameter, and if it is present, validate and parse it to a Date. If decoding succeeds, then the resulting value's type will be:

type ExampleDecodedResult = {
  id: number;
  time?: Date;
};

This type is properly inferred by TypeScript and can be used in destructuring like so:

import { pipe } from 'fp-ts/function';
import * as E from 'fp-ts/Either';

const { id, time } = pipe(
  ExampleHttpRequest.decode(request),
  E.getOrElseW((decodeErrors) => {
    someErrorHandler(decodeErrors);
  }),
);

to get request argument validation and parsing as a one-liner. These codecs can also be used from the client-side to get the type safety around making outgoing requests. An API client could hypothetically have a method like:

apiClient.request(route, ExampleHttpRequest, {
  id: 1337,
  time: new Date(),
});

If both the server and client use the same codec for the request, then it becomes possible to encode the API contract (or at least as much of it that is possible to express in the type system) and therefore someone calling the API can be confident that the server will correctly interpret a request if the arguments typecheck.

Example

Let's define the api-ts spec for a hypothetical message-user service. The conventional top-level export is an apiSpec value; for example:

apiSpec

import { apiSpec } from '@api-ts/io-ts-http';

import { GetMessage, CreateMessage } from './routes/message';
import { GetUser, CreateUser, PatchUser, UpdateUser, DeleteUser } from './routes/user';

/**
 * message-user service
 *
 * @version 1.0.0
 */
export const API = apiSpec({
  'api.v1.message': {
    get: GetMessage,
    post: CreateMessage,
  },
  'api.v1.user': {
    get: GetUser,
    post: CreateUser,
    put: UpdateUser,
    delete: DeleteUser,
    patch: PatchUser,
  },
});

The apiSpec is imported, along with some named httpRoutes ({Get|Create}Message, and {Get|Create|Update|Delete}User) which we'll discuss below.

Currently, if you add the @version JSDoc tag to the exported API spec, it will be used as the API version when generating an OpenAPI schema. Support for other tags may be added in the future.

The top-level export for message-user-types is API, which we define as an apiSpec with two endpoints api/v1/message and api/v1/user. The api/v1/message endpoint responds to GET and POST verbs while the second reponds to GET, POST, PUT, and DELETE verbs using httpRoutes defined in ./routes/message. The following are the httpRoutes defined in ./routes/message.

httpRoute

import * as t from 'io-ts';
import { httpRoute, httpRequest } from '@api-ts/io-ts-http';

export const GetMessage = httpRoute({
  path: '/message/{id}',
  method: 'GET',
  request: httpRequest({
    params: {
      id: t.string,
    },
  }),
  response: {
    200: t.type({
      id: t.string,
      message: t.string,
    }),
    404: t.type({
      error: t.string,
    }),
  },
});

export const CreateMessage = httpRoute({
  path: '/message',
  method: 'POST',
  request: httpRequest({
    body: {
      message: t.string,
    },
  }),
  response: {
    200: t.type({
      id: t.string,
      message: t.string,
    }),
    404: t.type({
      error: t.string,
    }),
  },
});

The first import is the io-ts package. It's usually imported as t for use in describing the types of data properties. Again, review io-ts documentation for more context on how to use it and this package.

Then httpRoute and httpRequest are imported. We'll review the httpRequest below, but first, let's review the GetMessage httpRoute.

export const GetMessage = httpRoute({
  path: '/message/{id}',
  method: 'GET',
  request: httpRequest({
    params: {
      id: t.string,
    },
  }),
  response: {
    200: t.type({
      id: t.string,
      message: t.string,
    }),
    404: t.type({
      error: t.string,
    }),
  },
});

httpRoutes apiSpecs use httpRoutes to define the path, method, request and response of a route.

path

The route's path along with possible path variables. You should surround variables with brackets like {name}, and are to the request codec under the params property.

method

The route's method is the HTTP request method to use for that route. In our GetMessage example, the method is GET, while in our PostMessage example, the method is POST.

request

The route's request is the output of the httpRequest function. This will be described below.

response

The route's response describes the possible HTTP responses the route can produce. The key-value pairs of the response object are an HTTP status code followed by the io-ts type of the response body. In our GetMessage example, a 200 status response yields a payload of a JSON object with two properties, message which is a string and id which is also a string, and a 404 yeilds a payload of a JSON object with a single property error which is a String.

httpRequest

Use httpRequest to build the expected type that you pass in a request to the route. In our example GetMessage

export const GetMessage = httpRoute({
  path: '/message/{id}',
  method: 'GET',
  request: httpRequest({
    params: {
      id: t.string,
    },
  }),
  // ...
});

httpRequests have a total of 4 optional properties: params (shown in the example), query, headers, and body.

params

params is an object representing the types of path parameters in a URL. Any URL parameters in the path property of an httpRoute must be accounted for in the params property of the httpRequest. Our request has a single URL parameter it is expecting, id. This is the type of this parameter is captured in the params object of our httpRequest.

query

query is the object representing the values passed in via query parameters at the end of a URL. The following example uses a new route, GetMessages, to our API that searches messages related to a specific author:

export const GetMessages = httpRoute({
  path: '/messages',
  method: 'GET',
  request: httpRequest({
    query: {
      author: t.string,
    },
  }),
  // ...
});

headers

headers is an object representing the types of the HTTP headers passed in with a request.

body

body is an object representing the type of the HTTP body of a request. Often this is a JSON object. The CreateMessage httpRoute in our example uses the body property:

export const CreateMessage = httpRoute({
  path: '/message',
  method: 'POST',
  request: httpRequest({
    body: {
      message: t.string,
    },
  }),
  // ...
});

Decoding an httpRequest

When you decode httpRequests using io-ts helpers, the properties of the request are flattened like this:

import { DateFromISOString, NumberFromString } from 'io-ts-types';

// build an httpRequest with one parameter id and a body with content and a timestamp
const Request = httpRequest({
  params: {
    id: NumberFromString,
  },
  body: {
    content: t.string,
    timestamp: DateFromISOString,
  },
});

// use io-ts to get the type of the Request
type Request = t.TypeOf<typeof Request>;

// same as
type Request = {
  id: number;
  content: string;
  timestamp: Date;
};

Documentation

版本与发布记录

@api-ts/io-ts-http 共发布 33 个版本,首次发布于 2022/04/19;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.2.4latest2026/08/053 个月前
3.2.32026/07/273 个月前
3.2.22026/07/223 个月前
3.2.12024/09/142 年前
3.2.02024/08/242 年前
3.1.12024/08/052 年前

其他发布通道:beta → 3.0.0-beta.1。

关于 @api-ts/io-ts-http 的常见问题

@api-ts/io-ts-http 是什么?

Types for (de)serializing HTTP requests from both the client and server side

如何安装 @api-ts/io-ts-http?

在项目目录运行 npm install @api-ts/io-ts-http,或使用 pnpm add / yarn add / bun add。

@api-ts/io-ts-http 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@api-ts/io-ts-http 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@api-ts/io-ts-http 可以商用吗?

@api-ts/io-ts-http 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@api-ts/io-ts-http 的下载量有多少?

根据 npm 官方下载统计,@api-ts/io-ts-http 在 2026/10/06 – 2026/11/04 这 30 天内被下载 171,554 次,日均约 5,718 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@api-ts/io-ts-http 还在维护吗?

最新版本 3.2.4 发布于 2026/08/05(3 个月前);至今共发布 33 个版本,其中过去 12 个月发布了 3 个;首次发布于 2022/04/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。