encore-service
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEncore Service Structure
Encore 服务结构
Instructions
操作说明
Creating a Service
创建服务
Every Encore service needs an file:
encore.service.tstypescript
// encore.service.ts
import { Service } from "encore.dev/service";
export default new Service("my-service");每个Encore服务都需要一个文件:
encore.service.tstypescript
// encore.service.ts
import { Service } from "encore.dev/service";
export default new Service("my-service");Minimal Service Structure
最小服务结构
my-service/
├── encore.service.ts # Service definition (required)
├── api.ts # API endpoints
└── db.ts # Database (if needed)my-service/
├── encore.service.ts # 服务定义(必填)
├── api.ts # API 端点
└── db.ts # 数据库(按需添加)Application Patterns
应用模式
Single Service (Recommended Start)
单服务(推荐入门方案)
Best for new projects - start simple, split later if needed:
my-app/
├── package.json
├── encore.app
├── encore.service.ts
├── api.ts
├── db.ts
└── migrations/
└── 001_initial.up.sql最适合新项目——从简单结构开始,按需拆分:
my-app/
├── package.json
├── encore.app
├── encore.service.ts
├── api.ts
├── db.ts
└── migrations/
└── 001_initial.up.sqlMulti-Service
多服务
For distributed systems with clear domain boundaries:
my-app/
├── encore.app
├── package.json
├── user/
│ ├── encore.service.ts
│ ├── api.ts
│ └── db.ts
├── order/
│ ├── encore.service.ts
│ ├── api.ts
│ └── db.ts
└── notification/
├── encore.service.ts
└── api.ts适用于具有清晰领域边界的分布式系统:
my-app/
├── encore.app
├── package.json
├── user/
│ ├── encore.service.ts
│ ├── api.ts
│ └── db.ts
├── order/
│ ├── encore.service.ts
│ ├── api.ts
│ └── db.ts
└── notification/
├── encore.service.ts
└── api.tsLarge Application (System-based)
大型应用(基于系统分组)
Group related services into systems:
my-app/
├── encore.app
├── commerce/
│ ├── order/
│ │ └── encore.service.ts
│ ├── cart/
│ │ └── encore.service.ts
│ └── payment/
│ └── encore.service.ts
├── identity/
│ ├── user/
│ │ └── encore.service.ts
│ └── auth/
│ └── encore.service.ts
└── comms/
├── email/
│ └── encore.service.ts
└── push/
└── encore.service.ts将相关服务按系统分组:
my-app/
├── encore.app
├── commerce/
│ ├── order/
│ │ └── encore.service.ts
│ ├── cart/
│ │ └── encore.service.ts
│ └── payment/
│ └── encore.service.ts
├── identity/
│ ├── user/
│ │ └── encore.service.ts
│ └── auth/
│ └── encore.service.ts
└── comms/
├── email/
│ └── encore.service.ts
└── push/
└── encore.service.tsService-to-Service Calls
服务间调用
Import other services from :
~encore/clientstypescript
import { user } from "~encore/clients";
export const getOrderWithUser = api(
{ method: "GET", path: "/orders/:id", expose: true },
async ({ id }): Promise<OrderWithUser> => {
const order = await getOrder(id);
const orderUser = await user.get({ id: order.userId });
return { ...order, user: orderUser };
}
);从导入其他服务:
~encore/clientstypescript
import { user } from "~encore/clients";
export const getOrderWithUser = api(
{ method: "GET", path: "/orders/:id", expose: true },
async ({ id }): Promise<OrderWithUser> => {
const order = await getOrder(id);
const orderUser = await user.get({ id: order.userId });
return { ...order, user: orderUser };
}
);When to Split Services
何时拆分服务
Split when you have:
| Signal | Action |
|---|---|
| Different scaling needs | Split (e.g., auth vs analytics) |
| Different deployment cycles | Split |
| Clear domain boundaries | Split |
| Shared database tables | Keep together |
| Tightly coupled logic | Keep together |
| Just organizing code | Use folders, not services |
出现以下情况时可考虑拆分:
| 信号 | 操作 |
|---|---|
| 不同的扩容需求 | 拆分(例如:认证服务 vs 分析服务) |
| 不同的部署周期 | 拆分 |
| 清晰的领域边界 | 拆分 |
| 共享数据库表 | 保持合并 |
| 逻辑高度耦合 | 保持合并 |
| 仅为代码整理 | 使用文件夹,而非拆分服务 |
Service with Middleware
带中间件的服务
typescript
import { Service } from "encore.dev/service";
import { middleware } from "encore.dev/api";
const loggingMiddleware = middleware(
{ target: { all: true } },
async (req, next) => {
console.log(`Request: ${req.requestMeta?.path}`);
return next(req);
}
);
export default new Service("my-service", {
middlewares: [loggingMiddleware],
});typescript
import { Service } from "encore.dev/service";
import { middleware } from "encore.dev/api";
const loggingMiddleware = middleware(
{ target: { all: true } },
async (req, next) => {
console.log(`Request: ${req.requestMeta?.path}`);
return next(req);
}
);
export default new Service("my-service", {
middlewares: [loggingMiddleware],
});Guidelines
指导原则
- Services cannot be nested within other services
- Start with one service, split when there's a clear reason
- Use for cross-service calls (never direct imports)
~encore/clients - Each service can have its own database
- Service names should be lowercase, descriptive
- Don't create services just for code organization - use folders instead
- 服务不能嵌套在其他服务内部
- 从单服务开始,有明确理由时再拆分
- 服务间调用请使用(禁止直接导入)
~encore/clients - 每个服务可拥有独立数据库
- 服务名称应使用小写、具有描述性
- 不要仅为代码整理而创建服务——改用文件夹