mcpField
E
encore-api

encore-api

github.com/encoredev开发30843 次安装2 天前更新
代码仓库

关于 encore-api

encore-api 是使用 Encore.ts 构建类型化 API 端点的技能指南,适合在 TypeScript 中定义 HTTP 路由、请求验证、错误处理和静态资源服务。

主要功能

  1. 01定义类型化 HTTP 端点
  2. 02映射路径、查询、标头和 Cookie 输入
  3. 03使用约束验证请求
  4. 04通过 APIError 返回 HTTP 错误
  5. 05提供静态资源和 SPA 回退路由

适用场景

  1. 01构建类型化 CRUD 端点
  2. 02验证传入的用户输入
  3. 03处理身份验证和资源错误
  4. 04为应用提供静态文件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/encoredev/skills --skill encore-api

安装后在 Claude Code 中输入/encore-api确认已加载。

详细介绍

Encore API 端点

说明

使用 Encore.ts 创建 API 端点时,请遵循以下模式:

1. 导入 API 模块
import { api } from "encore.dev/api";
2. 定义带类型的请求/响应接口

始终为请求和响应类型定义明确的 TypeScript 接口:

interface CreateUserRequest {
  email: string;
  name: string;
}

interface CreateUserResponse {
  id: string;
  email: string;
  name: string;
}
3. 创建端点
export const createUser = api(
  { method: "POST", path: "/users", expose: true },
  async (req: CreateUserRequest): Promise<CreateUserResponse> => {
    // Implementation
  }
);

API 选项

选项类型说明
methodstringHTTP 方法:GET、POST、PUT、PATCH、DELETE
pathstringURL 路径,支持 :param 和 *wildcard
exposeboolean若为 true,则可从外部访问(默认:false)
authboolean若为 true,则需要身份验证
sensitiveboolean若为 true,则会从跟踪记录中隐去请求/响应负载

请求/响应模式

Encore 支持四种端点配置:

// Both request and response
export const createUser = api(
  { method: "POST", path: "/users", expose: true },
  async (req: CreateRequest): Promise<CreateResponse> => { ... }
);

// Response only (no request body)
export const listUsers = api(
  { method: "GET", path: "/users", expose: true },
  async (): Promise<ListResponse> => { ... }
);

// Request only (no response body)
export const deleteUser = api(
  { method: "DELETE", path: "/users/:id", expose: true },
  async (req: DeleteRequest): Promise<void> => { ... }
);

// Neither request nor response
export const ping = api(
  { method: "GET", path: "/ping", expose: true },
  async (): Promise<void> => { ... }
);

自定义 HTTP 状态码

在响应中加入 HttpStatus 字段,即可返回自定义状态码:

import { api, HttpStatus } from "encore.dev/api";

interface CreateResponse {
  id: string;
  status: HttpStatus;
}

export const create = api(
  { method: "POST", path: "/items", expose: true },
  async (req: CreateRequest): Promise<CreateResponse> => {
    const item = await createItem(req);
    return { id: item.id, status: HttpStatus.Created };  // Returns 201
  }
);

参数类型

路径参数
// Path: "/users/:id"
interface GetUserRequest {
  id: string;  // Automatically mapped from :id
}
查询参数
import { Query } from "encore.dev/api";

interface ListUsersRequest {
  limit?: Query<number>;
  offset?: Query<number>;
}
标头
import { Header } from "encore.dev/api";

interface WebhookRequest {
  signature: Header<"X-Webhook-Signature">;
  payload: string;
}
Cookie
import { Cookie } from "encore.dev/api";

interface SessionRequest {
  session?: Cookie<"session">;
  settings?: Cookie<"user-settings">;
}

请求验证

Encore 会在运行时使用 TypeScript 类型验证请求。添加约束以进行更严格的验证:

import { api } from "encore.dev/api";
import { Min, Max, MinLen, MaxLen, IsEmail, IsURL } from "encore.dev/validate";

interface CreateUserRequest {
  email: string & IsEmail;                    // Must be valid email
  username: string & MinLen<3> & MaxLen<20>;  // 3-20 characters
  age: number & Min<13> & Max<120>;           // Between 13 and 120
  website?: string & IsURL;                   // Optional, must be URL if provided
}
组合验证规则

使用 & 表示 AND 逻辑(必须通过所有规则),使用 | 表示 OR 逻辑(必须至少通过一条规则):

import { IsEmail, IsURL, MinLen, MaxLen } from "encore.dev/validate";

interface ContactRequest {
  // Must be valid email OR valid URL
  contact: string & (IsEmail | IsURL);
  // Must be 5-100 chars AND be a valid URL
  website: string & MinLen<5> & MaxLen<100> & IsURL;
}
可用验证器
验证器适用于示例
Min<N>数字age: number & Min<18>
Max<N>数字count: number & Max<100>
MinLen<N>字符串、数组name: string & MinLen<1>
MaxLen<N>字符串、数组tags: string[] & MaxLen<10>
IsEmail字符串email: string & IsEmail
IsURL字符串link: string & IsURL
StartsWith<S>字符串id: string & StartsWith<"usr_">
EndsWith<S>字符串file: string & EndsWith<".json">
MatchesRegexp<R>字符串code: string & MatchesRegexp<"^[A-Z]{3}$">
验证错误响应

无效请求会返回 400,并附带详细信息:

{
  "code": "invalid_argument",
  "message": "validation failed",
  "details": { "field": "email", "error": "must be a valid email" }
}

错误处理

使用 APIError 返回正确的 HTTP 错误响应:

import { APIError, ErrCode } from "encore.dev/api";

// Throw with error code
throw new APIError(ErrCode.NotFound, "user not found");

// Or use shorthand
throw APIError.notFound("user not found");
throw APIError.invalidArgument("email is required");
throw APIError.unauthenticated("invalid token");

常见错误代码

代码HTTP 状态用途
NotFound404资源不存在
InvalidArgument400输入无效
Unauthenticated401缺少身份验证或身份验证无效
PermissionDenied403不允许执行
AlreadyExists409资源重复

静态资源

使用 api.static 提供静态文件(HTML、CSS、JS、图片):

import { api } from "encore.dev/api";

// Serve files from ./assets under /static/*
export const assets = api.static(
  { expose: true, path: "/static/*path", dir: "./assets" }
);

// Serve at root (use !path for fallback routing)
export const frontend = api.static(
  { expose: true, path: "/!path", dir: "./dist" }
);

// Custom 404 page
export const app = api.static(
  { expose: true, path: "/!path", dir: "./public", notFound: "./404.html" }
);
路径语法
  • *path - 标准通配符:匹配前缀下的所有路径(例如,/static/*path)
  • !path - 回退路由:在域名根目录提供静态文件,且不会与其他 API 端点冲突。适用于未匹配的路由应提供 index.html 的 SPA

指南

  • 始终使用 import,不要使用 require
  • 定义明确的接口以确保类型安全
  • 仅对公共端点使用 expose: true
  • 抛出 APIError,不要返回错误对象
  • 对于入站 Webhook(Stripe、GitHub 等),使用 api.raw — 请参阅 encore-webhook 技能
  • 路径参数会根据路径模式自动提取
  • 对用户输入使用验证约束(Min、MaxLen 等)

评论

支持 Markdown