|
1 | 1 | [![NPM version][npm-image]][npm-url] |
2 | | -[![build status][travis-image]][travis-url] |
3 | 2 | [![Test coverage][coveralls-image]][coveralls-url] |
4 | | -[![David deps][david-image]][david-url] |
5 | 3 | [![node version][node-image]][node-url] |
6 | 4 | [![npm download][download-image]][download-url] |
7 | 5 | [![npm license][license-image]][download-url] |
|
10 | 8 | [npm-image]: https://img.shields.io/npm/v/erest.svg?style=flat-square |
11 | 9 | [npm-url]: https://npmjs.org/package/erest |
12 | 10 | [travis-image]: https://img.shields.io/travis/yourtion/node-erest.svg?style=flat-square |
13 | | -[travis-url]: https://travis-ci.org/yourtion/node-erest |
14 | 11 | [coveralls-image]: https://img.shields.io/coveralls/yourtion/node-erest.svg?style=flat-square |
15 | 12 | [coveralls-url]: https://coveralls.io/r/yourtion/node-erest?branch=master |
16 | | -[david-image]: https://img.shields.io/david/yourtion/node-erest.svg?style=flat-square |
17 | 13 | [david-url]: https://david-dm.org/yourtion/node-erest |
18 | 14 | [node-image]: https://img.shields.io/badge/node.js-%3E=_10-green.svg?style=flat-square |
19 | 15 | [node-url]: http://nodejs.org/download/ |
20 | 16 | [download-image]: https://img.shields.io/npm/dm/erest.svg?style=flat-square |
21 | 17 | [download-url]: https://npmjs.org/package/erest |
22 | 18 | [license-image]: https://img.shields.io/npm/l/erest.svg |
23 | 19 |
|
24 | | -# node-erest |
| 20 | +# ERest |
25 | 21 |
|
26 | | -通过简单的方式构建一个优秀的 API 服务(基于 express、@leizm/web 等)。 |
| 22 | +🚀 **现代化的 TypeScript API 框架** - 通过简单的方式构建优秀的 API 服务 |
27 | 23 |
|
28 | | -一个优秀的 API 必须要有优秀的文档、较完整的测试,同时便于开发部署与联调。在文档方面,最大的问题在于,随着 API 的发展需要找人同步更新文档。有个更好的方案是不脱离代码自更新文档。 |
| 24 | +基于 Express、@leizm/web 等主流框架,ERest 提供了一套完整的 API 开发解决方案。支持自动文档生成、类型安全验证、测试脚手架等功能,让 API 开发更加高效和可靠。 |
29 | 25 |
|
30 | | -通过 ERest,你可以在定义 API 的同时,完成参数模型的定义、API格式的定义,同时生成便于写 API 测试的脚手架,像调用本地方法一样写 API 测试,并自动完成 API 文档的生成(包括示例数据),同时生成 Swagger、Postman、基于 axios 的 js-sdk(更多功能支持自定义)。 |
| 26 | +## ✨ 核心特性 |
31 | 27 |
|
32 | | -使用 (generator-erest)[https://github.com/yourtion/node-generator-erest] 帮助你快速生成一个 API 项目框架。 |
| 28 | +* 🔷 **TypeScript 原生支持** - 完整的类型推导和类型安全 |
33 | 29 |
|
34 | | -## Install |
| 30 | +* 🔧 **原生 Zod 集成** - 高性能的参数验证和类型推导 |
35 | 31 |
|
36 | | -```bash |
37 | | -$ npm install erest --save |
38 | | -``` |
| 32 | +* 📚 **自动文档生成** - 支持 Swagger、Postman、Markdown 等多种格式 |
| 33 | + |
| 34 | +* 🧪 **测试脚手架** - 像调用本地方法一样编写 API 测试 |
| 35 | + |
| 36 | +* 🔌 **多框架支持** - 兼容 Express、Koa、@leizm/web 等主流框架 |
| 37 | + |
| 38 | +* 📦 **SDK 自动生成** - 自动生成基于 axios 的客户端 SDK |
| 39 | + |
| 40 | +* 🎯 **零配置启动** - 开箱即用的开发体验 |
| 41 | + |
| 42 | +## 🛠️ 技术栈 |
39 | 43 |
|
40 | | -### Use yeoman generator |
| 44 | +* **语言**: TypeScript 5.8+ |
| 45 | + |
| 46 | +* **运行时**: Node.js 18+ |
| 47 | + |
| 48 | +* **验证库**: Zod 4.0+ |
| 49 | + |
| 50 | +* **支持框架**: Express 4.x, Koa 3.x, @leizm/web 2.x |
| 51 | + |
| 52 | +* **构建工具**: Vite, Biome |
| 53 | + |
| 54 | +* **测试框架**: Vitest |
| 55 | + |
| 56 | +## 📦 安装 |
41 | 57 |
|
42 | 58 | ```bash |
43 | | -$ npm install generator-erest -g |
44 | | -# Express |
45 | | -$ yo erest:express |
46 | | -# @leizm/web |
47 | | -$ yo erest:lei-web |
| 59 | +# npm |
| 60 | +npm install erest |
| 61 | + |
| 62 | +# yarn |
| 63 | +yarn add erest |
| 64 | + |
| 65 | +# pnpm |
| 66 | +pnpm add erest |
48 | 67 | ``` |
49 | 68 |
|
50 | | -## How to use |
| 69 | +### 快速开始脚手架 |
51 | 70 |
|
52 | | -```javascript |
53 | | -'use strict'; |
| 71 | +使用 快速生成项目框架: |
54 | 72 |
|
55 | | -const API = require('erest').default; |
| 73 | +```bash |
| 74 | +npm install generator-erest -g |
56 | 75 |
|
57 | | -// API info for document |
58 | | -const INFO = { |
59 | | - title: 'erest-demo', |
60 | | - description: 'Easy to write, easy to test, easy to generate document.', |
61 | | - version: new Date(), |
62 | | - host: 'http://127.0.0.1:3000', |
63 | | - basePath: '/api', |
64 | | -}; |
| 76 | +# Express 项目 |
| 77 | +yo erest:express |
65 | 78 |
|
66 | | -// API group info |
67 | | -const GROUPS = { |
68 | | - Index: '首页', |
69 | | -}; |
| 79 | +# @leizm/web 项目 |
| 80 | +yo erest:lei-web |
| 81 | +``` |
70 | 82 |
|
71 | | -// Init API |
72 | | -const apiService = new API({ |
73 | | - info: INFO, |
74 | | - groups: GROUPS, |
| 83 | +## 🚀 快速开始 |
| 84 | + |
| 85 | +### 基础用法 |
| 86 | + |
| 87 | +```typescript |
| 88 | +import ERest, { z } from 'erest'; |
| 89 | +import express from 'express'; |
| 90 | + |
| 91 | +// 创建 ERest 实例 |
| 92 | +const api = new ERest({ |
| 93 | + info: { |
| 94 | + title: 'My API', |
| 95 | + description: 'A powerful API built with ERest', |
| 96 | + version: new Date(), |
| 97 | + host: 'http://localhost:3000', |
| 98 | + basePath: '/api', |
| 99 | + }, |
| 100 | + groups: { |
| 101 | + user: '用户管理', |
| 102 | + post: '文章管理', |
| 103 | + }, |
75 | 104 | }); |
76 | 105 |
|
77 | | -apiService.api.get('/index') |
78 | | - .group('Index') |
79 | | - .title('Test api') |
80 | | - .register((req, res) => { |
81 | | - res.end('Hello, API Framework Index'); |
| 106 | +// 定义 API 接口 |
| 107 | +api.api.get('/users/:id') |
| 108 | + .group('user') |
| 109 | + .title('获取用户信息') |
| 110 | + .params(z.object({ |
| 111 | + id: z.string().describe('用户ID'), |
| 112 | + })) |
| 113 | + .query(z.object({ |
| 114 | + include: z.string().optional().describe('包含的关联数据'), |
| 115 | + })) |
| 116 | + .register(async (req, res) => { |
| 117 | + const { id } = req.params; |
| 118 | + const { include } = req.query; |
| 119 | + |
| 120 | + // 业务逻辑 |
| 121 | + const user = await getUserById(id, include); |
| 122 | + res.json({ success: true, data: user }); |
82 | 123 | }); |
83 | 124 |
|
84 | | -const express = require('express'); |
| 125 | +// 绑定到 Express |
85 | 126 | const app = express(); |
86 | | -const router = new express.Router(); |
| 127 | +const router = express.Router(); |
87 | 128 | app.use('/api', router); |
88 | 129 |
|
89 | | -// bing express router |
90 | | -apiService.bindRouter(router, apiService.checkerExpress); |
| 130 | +api.bindRouter(router, api.checkerExpress); |
| 131 | + |
| 132 | +app.listen(3000, () => { |
| 133 | + console.log('🚀 Server running on http://localhost:3000'); |
| 134 | +}); |
| 135 | +``` |
| 136 | + |
| 137 | +### 原生 Zod 类型支持 |
| 138 | + |
| 139 | +```typescript |
| 140 | +import { z } from 'erest'; |
| 141 | + |
| 142 | +// 定义复杂的数据模型 |
| 143 | +const CreateUserSchema = z.object({ |
| 144 | + name: z.string().min(1).max(50), |
| 145 | + email: z.string().email(), |
| 146 | + age: z.number().int().min(18).max(120), |
| 147 | + tags: z.array(z.string()).optional(), |
| 148 | + profile: z.object({ |
| 149 | + bio: z.string().optional(), |
| 150 | + avatar: z.string().url().optional(), |
| 151 | + }).optional(), |
| 152 | +}); |
| 153 | + |
| 154 | +api.api.post('/users') |
| 155 | + .group('user') |
| 156 | + .title('创建用户') |
| 157 | + .body(CreateUserSchema) |
| 158 | + .register(async (req, res) => { |
| 159 | + // req.body 自动获得完整的类型推导 |
| 160 | + const userData = req.body; // 类型安全! |
| 161 | + |
| 162 | + const user = await createUser(userData); |
| 163 | + res.json({ success: true, data: user }); |
| 164 | + }); |
| 165 | +``` |
| 166 | + |
| 167 | +### 自动文档生成 |
91 | 168 |
|
92 | | -app.listen(3000, function () { |
93 | | - console.log('erest-demo listening started'); |
| 169 | +```typescript |
| 170 | +// 生成多种格式的文档 |
| 171 | +api.docs.generateDocs({ |
| 172 | + swagger: './docs/swagger.json', |
| 173 | + markdown: './docs/api.md', |
| 174 | + postman: './docs/postman.json', |
| 175 | + axios: './sdk/api-client.js', |
94 | 176 | }); |
95 | 177 | ``` |
0 commit comments