@di-framework/http

中文文档
6.1.0发布于 2026/10/12(MIT OR Apache-2.0)TypeScriptES Module构建来源已验证近 30 天下载 3136

Extends di-framework with HTTP features

原始使用文档
文档目录14 节
  1. Features
  2. Installation
  3. Quick Start
  4. 1. Create a Controller (DI-aware)
  5. 2. Multipart File Uploads
  6. OpenAPI Generation
  7. API Reference
  8. TypedRouter<Args[]>()
  9. json<T>(data: T, init?: ResponseInit)
  10. Json<T> / Multipart<T>
  11. @Controller(options?)
  12. @Endpoint(metadata)
  13. Portable runtime imports
  14. License

@di-framework/http

Lightweight TypeScript decorators and a type-safe router for itty-router. Includes a build-time OpenAPI 3.1 generator. Ported from itty-decorators.

Features

  • Type-Safe Routing: TypedRouter provides full TypeScript support for request bodies, response types, and context.
  • Auto JSON Enforcement: Automatically validates Content-Type: application/json for mutation methods (POST, PUT, PATCH).
  • Multipart Support: Opt into multipart/form-data handling with Multipart<T> and { multipart: true }.
  • Declarative Metadata: Use @Controller and @Endpoint decorators to document your API logic directly in code.
  • DI Integration: @Controller composes the core DI @Container decorator, so controllers are auto-registered and can use @Component injection and useContainer().resolve(...).
  • OpenAPI 3.1 Support: Generate a complete OpenAPI specification from your code at build time.
  • Minimal Footprint: Built on top of the ultra-light itty-router.

Installation

# Install the HTTP package and the core DI framework (peer dependency)
bun add @di-framework/http @di-framework/core
# or
npm install @di-framework/http @di-framework/core

Quick Start

1. Create a Controller (DI-aware)

Annotate your API logic using decorators and the TypedRouter. Controllers are automatically registered with the DI container, so you can inject services and resolve the controller instance.

import {
  TypedRouter,
  json,
  type RequestSpec,
  type ResponseSpec,
  type Json,
  Controller,
  Endpoint,
} from '@di-framework/http';
import { Component, Container } from '@di-framework/core/decorators';
import { useContainer } from '@di-framework/core/container';

const router = TypedRouter();

type EchoPayload = { message: string };
type EchoResponse = { echoed: string; timestamp: string };

// Example DI-managed service
@Container()
export class LoggerService {
  log(msg: string) {
    console.log(msg);
  }
}

@Controller()
export class EchoController {
  // Because @Controller composes the core @Container decorator, this class is
  // automatically registered with the DI container. We can inject services.
  @Component(LoggerService)
  private logger!: LoggerService;

  echoMessage(message: string): EchoResponse {
    this.logger.log(`Echoing: ${message}`);
    return { echoed: message, timestamp: new Date().toISOString() };
  }

  @Endpoint({
    summary: 'Echo a message',
    description: 'Returns the provided message with a server timestamp.',
    responses: {
      '200': { description: 'Successful echo' },
    },
  })
  static post = router.post<RequestSpec<Json<EchoPayload>>, ResponseSpec<EchoResponse>>(
    '/echo',
    (req) => {
      // Demonstrate auto DI registration: resolve the controller instance from
      // the global container without any manual registration.
      const controller = useContainer().resolve(EchoController);
      return json(controller.echoMessage(req.content.message));
    },
  );
}

// Add a simple GET route
router.get('/', () => json({ message: 'API is healthy' }));

export default {
  fetch: (request: Request, env: any, ctx: any) => router.fetch(request, env, ctx),
};

2. Multipart File Uploads

Use Multipart<T> and { multipart: true } to accept multipart/form-data instead of JSON. The handler receives req.content typed as FormData.

import {
  TypedRouter,
  json,
  type RequestSpec,
  type ResponseSpec,
  type Multipart,
} from '@di-framework/http';

const router = TypedRouter();

type UploadPayload = { files: File[] };
type UploadResult = { filenames: string[] };

router.post<RequestSpec<Multipart<UploadPayload>>, ResponseSpec<UploadResult>>(
  '/upload',
  (req) => {
    // req.content is typed as FormData
    const files = req.content.getAll('files') as File[];
    return json({ filenames: files.map((f) => f.name) });
  },
  { multipart: true },
);

OpenAPI Generation

The package exposes CLI-independent OpenAPI operations. Controller loading, document generation, and writing are explicit:

import { generateOpenAPIDocument, writeOpenAPIDocument } from '@di-framework/http';

const result = await generateOpenAPIDocument({
  controllerModules: ['./src/index.ts'],
  configuration: { title: 'My API', version: '1.0.0' },
});

writeOpenAPIDocument(result.document, './openapi.json');

The unified command is di-framework http openapi generate; terminal output and exit codes belong to @di-framework/cli.

Manual Generation

You can also generate the spec programmatically using the generateOpenAPI function and the default registry:

import registry, { generateOpenAPI } from '@di-framework/http';
import './controllers/MyController'; // Import to trigger registration

const spec = generateOpenAPI(
  {
    title: 'My API',
    version: '1.0.0',
  },
  registry,
);

console.log(JSON.stringify(spec, null, 2));

If you need full control, you can iterate the registry manually:

import registry from '@di-framework/http';

for (const target of registry.getTargets()) {
  // target is the decorated class
  // target[methodName].isEndpoint will be true
  // target[methodName].metadata contains your @Endpoint info
}

API Reference

TypedRouter<Args[]>()

A proxy for itty-router that enables type-safe method definitions.

  • Args: An array of types representing additional arguments passed to fetch (e.g., [Env, ExecutionContext]).

json<T>(data: T, init?: ResponseInit)

A typed wrapper around itty-router's json helper.

Json<T> / Multipart<T>

Body spec markers used with RequestSpec<> to declare the expected content type. Json<T> types req.content as T; Multipart<T> types it as FormData. Multipart routes require passing { multipart: true } as the third argument to the route method.

@Controller(options?)

Composed decorator that:

  • Marks a class for inclusion in the OpenAPI registry; and
  • Registers the class with the core DI container (same instance as @di-framework/core).

Options: { singleton?: boolean; container?: DIContainer }

@Endpoint(metadata)

Method or property decorator that attaches OpenAPI metadata.

  • summary: Short summary of the operation.
  • description: Verbose explanation.
  • requestBody: OpenAPI Request Body object.
  • responses: OpenAPI Responses object.

Portable runtime imports

The wasmcloud export condition selects a runtime entry without filesystem packaging, file streaming, or OpenAPI file generation. Other portable bundlers can import @di-framework/http/portable explicitly. Package static assets with the native packageStaticAssets API at build time, then pass the resulting package to router.static() or register it with registerStaticAssets.

Native imports from @di-framework/http retain disk serving, packaging, and OpenAPI file generation. The portable entry retains routing, in-memory OpenAPI schema generation, packaged text and binary assets, conditional requests, HEAD, and the same path validation.

License

Licensed under either MIT or Apache-2.0, at your option.

版本与发布记录

@di-framework/http 共发布 40 个版本,首次发布于 2026/08/03;过去 12 个月发布了 40 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
6.1.0latest2026/10/121 个月前
6.0.72026/10/121 个月前
6.0.62026/10/091 个月前
6.0.52026/10/071 个月前
6.0.42026/10/041 个月前
6.0.32026/10/021 个月前

关于 @di-framework/http 的常见问题

@di-framework/http 是什么?

Extends di-framework with HTTP features

如何安装 @di-framework/http?

在项目目录运行 npm install @di-framework/http,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:typescript(^5)、@di-framework/core(^6)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@di-framework/http 支持 TypeScript 吗?

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

@di-framework/http 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@di-framework/http 可以商用吗?

@di-framework/http 使用 (MIT OR Apache-2.0) 许可。可在 MIT、Apache-2.0 中任选其一遵守。选择 MIT 时,宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@di-framework/http 的下载量有多少?

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

@di-framework/http 还在维护吗?

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