本文档详细介绍 Grape 提供的所有 API 端点和使用方法。
http://localhost:4873
| 分类 | 说明 | 认证要求 |
|---|---|---|
| npm Registry API | 兼容 npm 协议的 API | 部分需要 |
| 管理 API | 包查询、统计等 | 可选 |
| 管理员 API | 用户管理、Webhook 配置 | 必须管理员 |
需要认证的 API 使用 Bearer Token 方式:
Authorization: Bearer <jwt_token>通过 npm login 命令获取:
npm login --registry http://localhost:4873响应:
{
"ok": true,
"id": "org.couchdb.user:admin",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Token 会保存在 ~/.npmrc 文件中:
//localhost:4873/:_authToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...默认 24 小时,可通过配置调整:
auth:
jwt_expiry: 8h # 8 小时获取包元数据。
请求:
GET /:package
Accept: application/json响应 200 OK:
{
"_id": "@grape/cli",
"name": "@grape/cli",
"dist-tags": {
"latest": "1.2.3",
"beta": "2.0.0-beta.1"
},
"versions": {
"1.2.3": {
"name": "@grape/cli",
"version": "1.2.3",
"dist": {
"shasum": "abc123...",
"tarball": "http://localhost:4873/@grape/cli/-/cli-1.2.3.tgz"
}
}
},
"time": {
"created": "2024-01-01T00:00:00Z",
"1.2.3": "2024-01-02T00:00:00Z"
},
"maintainers": [
{
"name": "admin",
"email": "admin@grape.local"
}
],
"description": "Grape CLI tool",
"readme": "# @grape/cli\n...",
"license": "MIT"
}响应 404 Not Found:
{
"code": 4041,
"message": "package not found"
}示例:
# 获取包信息
curl http://localhost:4873/lodash
# 获取 scoped 包信息
curl http://localhost:4873/@babel/core下载包的 tarball 文件。
请求:
GET /:package/-/:filename响应 200 OK:
Content-Type: application/octet-stream
Content-Length: 12345
<tarball binary data>
响应 404 Not Found:
{
"code": 4040,
"message": "resource not found"
}示例:
# 下载 tarball
curl -O http://localhost:4873/lodash/-/lodash-4.17.21.tgz
# 使用 npm 安装(自动调用此 API)
npm install lodash --registry http://localhost:4873发布新包或新版本。
请求:
PUT /:package
Authorization: Bearer <token>
Content-Type: application/json请求体:
{
"_id": "@grape/cli",
"name": "@grape/cli",
"description": "Grape CLI tool",
"dist-tags": {
"latest": "1.2.3"
},
"versions": {
"1.2.3": {
"name": "@grape/cli",
"version": "1.2.3",
"dist": {
"shasum": "abc123...",
"tarball": "@grape-cli-1.2.3.tgz"
}
}
},
"_attachments": {
"@grape-cli-1.2.3.tgz": {
"content_type": "application/octet-stream",
"data": "<base64 encoded tarball>"
}
},
"readme": "# @grape/cli\n..."
}响应 201 Created:
{
"ok": true,
"rev": "1-@grape/cli",
"success": true
}响应 401 Unauthorized:
{
"code": 4010,
"message": "authentication required"
}响应 409 Conflict:
{
"code": 4091,
"message": "version already exists"
}示例:
# 使用 npm 发布
npm publish --registry http://localhost:4873删除包或特定版本。
请求:
DELETE /:package
Authorization: Bearer <token>或删除特定版本:
DELETE /:package/-/:filename
Authorization: Bearer <token>响应 200 OK:
{
"ok": true
}响应 403 Forbidden:
{
"code": 4030,
"message": "insufficient permissions"
}示例:
# 删除特定版本
npm unpublish @grape/cli@1.2.3 --registry http://localhost:4873
# 删除整个包(谨慎操作)
npm unpublish @grape/cli --force --registry http://localhost:4873用户登录或注册。
请求:
PUT /-/user/org.couchdb.user:admin
Content-Type: application/json请求体:
{
"name": "admin",
"password": "admin123",
"email": "admin@example.com",
"type": "user"
}响应 200 OK (登录成功):
{
"ok": true,
"id": "org.couchdb.user:admin",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}响应 201 Created (注册成功):
{
"ok": true,
"id": "org.couchdb.user:newuser",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}响应 401 Unauthorized:
{
"error": "invalid credentials"
}响应 403 Forbidden:
{
"error": "registration is disabled, contact your administrator"
}示例:
# 使用 npm 登录
npm login --registry http://localhost:4873
# 或使用 curl
curl -X PUT http://localhost:4873/-/user/org.couchdb.user:admin \
-H "Content-Type: application/json" \
-d '{"name":"admin","password":"admin123"}'健康检查。
请求:
GET /-/health响应 200 OK:
{
"status": "ok",
"time": "2024-01-01T12:00:00Z"
}示例:
curl http://localhost:4873/-/healthPrometheus 格式的性能指标。
请求:
GET /-/metrics响应 200 OK:
# HELP grape_http_requests_total Total number of HTTP requests
# TYPE grape_http_requests_total counter
grape_http_requests_total{method="GET",path="/:package",status="200"} 1234
grape_http_requests_total{method="GET",path="/-/health",status="200"} 567
# HELP grape_http_request_duration_seconds HTTP request duration in seconds
# TYPE grape_http_request_duration_seconds histogram
grape_http_request_duration_seconds_bucket{method="GET",path="/:package",le="0.1"} 1000
...
# HELP grape_package_downloads_total Total number of package tarball downloads
# TYPE grape_package_downloads_total counter
grape_package_downloads_total{package="lodash"} 500
grape_package_downloads_total{package="express"} 300
# HELP grape_stored_packages_total Total number of packages stored locally
# TYPE grape_stored_packages_total gauge
grape_stored_packages_total 42
# HELP grape_registered_users_total Total number of registered users
# TYPE grape_registered_users_total gauge
grape_registered_users_total 5
示例:
curl http://localhost:4873/-/metrics获取所有已缓存的包列表。
请求:
GET /-/api/packages
Authorization: Bearer <token> # 可选响应 200 OK:
{
"packages": [
{
"name": "lodash",
"description": "Lodash modular utilities",
"version": "4.17.21",
"private": false,
"updatedAt": "2024-01-01 12:00:00"
},
{
"name": "@grape/cli",
"description": "Grape CLI tool",
"version": "1.2.3",
"private": true,
"updatedAt": "2024-01-02 15:30:00"
}
]
}示例:
curl http://localhost:4873/-/api/packages获取统计信息。
请求:
GET /-/api/stats
Authorization: Bearer <token> # 可选响应 200 OK:
{
"totalPackages": 42,
"storageSize": 128,
"upstreams": [
{
"name": "npmjs",
"url": "https://registry.npmjs.org",
"scope": "",
"enabled": true
},
{
"name": "company-private",
"url": "https://npm.company.com",
"scope": "@company",
"enabled": true
}
]
}字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
totalPackages |
int | 已缓存的包总数 |
storageSize |
int | 存储占用(MB) |
upstreams |
[]Upstream | 上游配置列表 |
示例:
curl http://localhost:4873/-/api/stats搜索包。
请求:
GET /-/api/search?q=lodash
Authorization: Bearer <token> # 可选响应 200 OK:
{
"packages": [
{
"name": "lodash",
"description": "Lodash modular utilities",
"version": "4.17.21",
"private": false
},
{
"name": "lodash-es",
"description": "Lodash ES module utilities",
"version": "4.17.21",
"private": false
}
],
"total": 2
}查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
q |
string | 是 | 搜索关键词(支持包名和描述) |
示例:
# 搜索包名
curl "http://localhost:4873/-/api/search?q=lodash"
# 搜索描述
curl "http://localhost:4873/-/api/search?q=utility"获取上游配置。
请求:
GET /-/api/upstreams
Authorization: Bearer <token> # 可选响应 200 OK:
{
"upstreams": [
{
"name": "npmjs",
"url": "https://registry.npmjs.org",
"scope": "",
"enabled": true
},
{
"name": "company-private",
"url": "https://npm.company.com",
"scope": "@company",
"enabled": true
}
]
}示例:
curl http://localhost:4873/-/api/upstreams获取当前用户信息。
请求:
GET /-/api/user
Authorization: Bearer <token>响应 200 OK:
{
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"createdAt": "2024-01-01T00:00:00Z",
"lastLogin": "2024-01-02T12:00:00Z"
}响应 401 Unauthorized:
{
"error": "not authenticated"
}示例:
curl http://localhost:4873/-/api/user \
-H "Authorization: Bearer <token>"用户登出。
请求:
DELETE /-/api/session
Authorization: Bearer <token>响应 200 OK:
{
"ok": true
}示例:
curl -X DELETE http://localhost:4873/-/api/session \
-H "Authorization: Bearer <token>"以下 API 需要管理员权限(role: admin)。
获取用户列表。
请求:
GET /-/api/admin/users
Authorization: Bearer <admin_token>响应 200 OK:
{
"users": [
{
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"createdAt": "2024-01-01T00:00:00Z",
"lastLogin": "2024-01-02T12:00:00Z"
},
{
"username": "developer",
"email": "dev@example.com",
"role": "developer",
"createdAt": "2024-01-01T10:00:00Z",
"lastLogin": "2024-01-02T09:00:00Z"
}
]
}示例:
curl http://localhost:4873/-/api/admin/users \
-H "Authorization: Bearer <admin_token>"创建新用户。
请求:
POST /-/api/admin/users
Authorization: Bearer <admin_token>
Content-Type: application/json请求体:
{
"name": "newuser",
"password": "SecurePass123!",
"email": "newuser@example.com",
"role": "developer"
}响应 201 Created:
{
"ok": true,
"username": "newuser",
"role": "developer"
}响应 400 Bad Request:
{
"error": "password must be at least 8 characters"
}响应 409 Conflict:
{
"error": "user already exists"
}字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name |
string | 是 | 用户名 |
password |
string | 是 | 密码(至少 8 字符) |
email |
string | 否 | 邮箱 |
role |
string | 否 | 角色:admin 或 developer,默认 developer |
示例:
curl -X POST http://localhost:4873/-/api/admin/users \
-H "Authorization: Bearer <admin_token>" \
-H "Content-Type: application/json" \
-d '{"name":"newuser","password":"SecurePass123!","email":"newuser@example.com"}'更新用户信息。
请求:
PUT /-/api/admin/users/admin
Authorization: Bearer <admin_token>
Content-Type: application/json请求体:
{
"email": "newemail@example.com",
"password": "NewSecurePass123!", // 可选,留空则不修改
"role": "admin" // 可选
}响应 200 OK:
{
"ok": true,
"username": "admin"
}示例:
curl -X PUT http://localhost:4873/-/api/admin/users/developer \
-H "Authorization: Bearer <admin_token>" \
-H "Content-Type: application/json" \
-d '{"email":"newdev@example.com"}'删除用户。
请求:
DELETE /-/api/admin/users/developer
Authorization: Bearer <admin_token>响应 200 OK:
{
"ok": true
}响应 403 Forbidden:
{
"error": "cannot delete admin user"
}示例:
curl -X DELETE http://localhost:4873/-/api/admin/users/developer \
-H "Authorization: Bearer <admin_token>"获取 Webhook 列表。
请求:
GET /-/api/admin/webhooks
Authorization: Bearer <admin_token>响应 200 OK:
{
"webhooks": [
{
"id": 1,
"name": "Slack Notification",
"url": "https://hooks.slack.com/services/xxx",
"events": "package:published,package:unpublished",
"enabled": true,
"createdAt": "2024-01-01T00:00:00Z",
"lastDeliveryAt": "2024-01-02T12:00:00Z"
}
]
}创建 Webhook。
请求:
POST /-/api/admin/webhooks
Authorization: Bearer <admin_token>
Content-Type: application/json请求体:
{
"name": "Slack Notification",
"url": "https://hooks.slack.com/services/xxx",
"secret": "hmac-secret-key",
"events": "package:published,package:unpublished",
"enabled": true
}响应 201 Created:
{
"ok": true,
"id": 1
}字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name |
string | 是 | Webhook 名称 |
url |
string | 是 | 接收端点 URL |
secret |
string | 否 | HMAC 签名密钥 |
events |
string | 否 | 逗号分隔的事件类型,空表示所有事件 |
enabled |
bool | 否 | 是否启用,默认 true |
事件类型:
| 事件 | 说明 |
|---|---|
package:published |
包发布 |
package:unpublished |
包删除 |
user:created |
用户创建 |
user:deleted |
用户删除 |
更新 Webhook。
请求:
PUT /-/api/admin/webhooks/1
Authorization: Bearer <admin_token>
Content-Type: application/json请求体:
{
"name": "Updated Name",
"url": "https://new-url.com/webhook",
"enabled": false
}删除 Webhook。
请求:
DELETE /-/api/admin/webhooks/1
Authorization: Bearer <admin_token>测试 Webhook。
请求:
POST /-/api/admin/webhooks/1/test
Authorization: Bearer <admin_token>响应 200 OK:
{
"ok": true,
"message": "Test event sent"
}{
"code": 4041,
"message": "package not found",
"reason": "lodash"
}| 错误码 | HTTP 状态 | 说明 |
|---|---|---|
4000 |
400 | 错误请求 |
4001 |
400 | 无效请求体 |
4010 |
401 | 需要认证 |
4011 |
401 | 凭证无效 |
4030 |
403 | 权限不足 |
4040 |
404 | 资源不存在 |
4041 |
404 | 包不存在 |
4042 |
404 | 用户不存在 |
4090 |
409 | 资源冲突 |
4091 |
409 | 版本已存在 |
4092 |
409 | 用户已存在 |
4290 |
429 | 请求过于频繁 |
5000 |
500 | 服务器内部错误 |
# 1. 登录获取 token
TOKEN=$(curl -s -X PUT http://localhost:4873/-/user/org.couchdb.user:admin \
-H "Content-Type: application/json" \
-d '{"name":"admin","password":"admin123"}' \
| jq -r '.token')
# 2. 获取当前用户信息
curl http://localhost:4873/-/api/user \
-H "Authorization: Bearer $TOKEN"
# 3. 获取包列表
curl http://localhost:4873/-/api/packages \
-H "Authorization: Bearer $TOKEN"
# 4. 获取统计信息
curl http://localhost:4873/-/api/stats# 登录
npm login --registry http://localhost:4873
# 安装包
npm install lodash --registry http://localhost:4873
# 发布包
npm publish --registry http://localhost:4873
# 删除包
npm unpublish my-package@1.0.0 --registry http://localhost:4873- 使用指南 - 包管理器配置
- Webhook 文档 - Webhook 详细使用
- 配置指南 - 配置文件说明