Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ name: "CodeQL"

on:
push:
branches: [master]
branches: [main]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
branches: [main]
schedule:
- cron: '0 17 * * 0'

Expand Down
53 changes: 53 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Test

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x, 20.x, 22.x]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: latest

- name: Install dependencies
run: pnpm install

- name: Run code format check
run: pnpm run check

- name: Build project
run: pnpm run build

- name: Run tests
run: pnpm run test:lib

- name: Run tests with coverage
run: pnpm run test:cov
if: matrix.node-version == '20.x'

- name: Upload coverage to Coveralls
uses: coverallsapp/github-action@v2
if: matrix.node-version == '20.x'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coverage/lcov.info
5 changes: 0 additions & 5 deletions .prettierrc.js

This file was deleted.

38 changes: 0 additions & 38 deletions .vscode/launch.json

This file was deleted.

182 changes: 132 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][coveralls-image]][coveralls-url]
[![David deps][david-image]][david-url]
[![node version][node-image]][node-url]
[![npm download][download-image]][download-url]
[![npm license][license-image]][download-url]
Expand All @@ -10,86 +8,170 @@
[npm-image]: https://img.shields.io/npm/v/erest.svg?style=flat-square
[npm-url]: https://npmjs.org/package/erest
[travis-image]: https://img.shields.io/travis/yourtion/node-erest.svg?style=flat-square
[travis-url]: https://travis-ci.org/yourtion/node-erest
[coveralls-image]: https://img.shields.io/coveralls/yourtion/node-erest.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/yourtion/node-erest?branch=master
[david-image]: https://img.shields.io/david/yourtion/node-erest.svg?style=flat-square
[david-url]: https://david-dm.org/yourtion/node-erest
[node-image]: https://img.shields.io/badge/node.js-%3E=_10-green.svg?style=flat-square
[node-url]: http://nodejs.org/download/
[download-image]: https://img.shields.io/npm/dm/erest.svg?style=flat-square
[download-url]: https://npmjs.org/package/erest
[license-image]: https://img.shields.io/npm/l/erest.svg

# node-erest
# ERest

通过简单的方式构建一个优秀的 API 服务(基于 express、@leizm/web 等)。
🚀 **现代化的 TypeScript API 框架** - 通过简单的方式构建优秀的 API 服务

一个优秀的 API 必须要有优秀的文档、较完整的测试,同时便于开发部署与联调。在文档方面,最大的问题在于,随着 API 的发展需要找人同步更新文档。有个更好的方案是不脱离代码自更新文档
基于 Express、@leizm/web 等主流框架,ERest 提供了一套完整的 API 开发解决方案。支持自动文档生成、类型安全验证、测试脚手架等功能,让 API 开发更加高效和可靠

通过 ERest,你可以在定义 API 的同时,完成参数模型的定义、API格式的定义,同时生成便于写 API 测试的脚手架,像调用本地方法一样写 API 测试,并自动完成 API 文档的生成(包括示例数据),同时生成 Swagger、Postman、基于 axios 的 js-sdk(更多功能支持自定义)。
## ✨ 核心特性

使用 (generator-erest)[https://github.com/yourtion/node-generator-erest] 帮助你快速生成一个 API 项目框架。
* 🔷 **TypeScript 原生支持** - 完整的类型推导和类型安全

## Install
* 🔧 **原生 Zod 集成** - 高性能的参数验证和类型推导

```bash
$ npm install erest --save
```
* 📚 **自动文档生成** - 支持 Swagger、Postman、Markdown 等多种格式

* 🧪 **测试脚手架** - 像调用本地方法一样编写 API 测试

* 🔌 **多框架支持** - 兼容 Express、Koa、@leizm/web 等主流框架

* 📦 **SDK 自动生成** - 自动生成基于 axios 的客户端 SDK

* 🎯 **零配置启动** - 开箱即用的开发体验

## 🛠️ 技术栈

### Use yeoman generator
* **语言**: TypeScript 5.8+

* **运行时**: Node.js 18+

* **验证库**: Zod 4.0+

* **支持框架**: Express 4.x, Koa 3.x, @leizm/web 2.x

* **构建工具**: Vite, Biome

* **测试框架**: Vitest

## 📦 安装

```bash
$ npm install generator-erest -g
# Express
$ yo erest:express
# @leizm/web
$ yo erest:lei-web
# npm
npm install erest

# yarn
yarn add erest

# pnpm
pnpm add erest
```

## How to use
### 快速开始脚手架

```javascript
'use strict';
使用 快速生成项目框架:

const API = require('erest').default;
```bash
npm install generator-erest -g

// API info for document
const INFO = {
title: 'erest-demo',
description: 'Easy to write, easy to test, easy to generate document.',
version: new Date(),
host: 'http://127.0.0.1:3000',
basePath: '/api',
};
# Express 项目
yo erest:express

// API group info
const GROUPS = {
Index: '首页',
};
# @leizm/web 项目
yo erest:lei-web
```

// Init API
const apiService = new API({
info: INFO,
groups: GROUPS,
## 🚀 快速开始

### 基础用法

```typescript
import ERest, { z } from 'erest';
import express from 'express';

// 创建 ERest 实例
const api = new ERest({
info: {
title: 'My API',
description: 'A powerful API built with ERest',
version: new Date(),
host: 'http://localhost:3000',
basePath: '/api',
},
groups: {
user: '用户管理',
post: '文章管理',
},
});

apiService.api.get('/index')
.group('Index')
.title('Test api')
.register((req, res) => {
res.end('Hello, API Framework Index');
// 定义 API 接口
api.api.get('/users/:id')
.group('user')
.title('获取用户信息')
.params(z.object({
id: z.string().describe('用户ID'),
}))
.query(z.object({
include: z.string().optional().describe('包含的关联数据'),
}))
.register(async (req, res) => {
const { id } = req.params;
const { include } = req.query;

// 业务逻辑
const user = await getUserById(id, include);
res.json({ success: true, data: user });
});

const express = require('express');
// 绑定到 Express
const app = express();
const router = new express.Router();
const router = express.Router();
app.use('/api', router);

// bing express router
apiService.bindRouter(router, apiService.checkerExpress);
api.bindRouter(router, api.checkerExpress);

app.listen(3000, () => {
console.log('🚀 Server running on http://localhost:3000');
});
```

### 原生 Zod 类型支持

```typescript
import { z } from 'erest';

// 定义复杂的数据模型
const CreateUserSchema = z.object({
name: z.string().min(1).max(50),
email: z.string().email(),
age: z.number().int().min(18).max(120),
tags: z.array(z.string()).optional(),
profile: z.object({
bio: z.string().optional(),
avatar: z.string().url().optional(),
}).optional(),
});

api.api.post('/users')
.group('user')
.title('创建用户')
.body(CreateUserSchema)
.register(async (req, res) => {
// req.body 自动获得完整的类型推导
const userData = req.body; // 类型安全!

const user = await createUser(userData);
res.json({ success: true, data: user });
});
```

### 自动文档生成

app.listen(3000, function () {
console.log('erest-demo listening started');
```typescript
// 生成多种格式的文档
api.docs.generateDocs({
swagger: './docs/swagger.json',
markdown: './docs/api.md',
postman: './docs/postman.json',
axios: './sdk/api-client.js',
});
```
38 changes: 38 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"$schema": "https://biomejs.dev/schemas/2.1.2/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"includes": ["src/**/*.ts", "src/**/*.js"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 120
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"trailingCommas": "es5"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
1 change: 1 addition & 0 deletions docs/assets/hierarchy.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading