diff --git a/docs/en-US/development/http-api/action-api.md b/docs/en-US/api/http/action-api.md similarity index 69% rename from docs/en-US/development/http-api/action-api.md rename to docs/en-US/api/http/action-api.md index 26fd5e1b8e..1445d05e54 100644 --- a/docs/en-US/development/http-api/action-api.md +++ b/docs/en-US/api/http/action-api.md @@ -4,7 +4,7 @@ --- -Collection 和 Association 资源通用。 +Collection and Association resources are common. ### `create` @@ -15,12 +15,12 @@ POST /api/users:create?whitelist=a,b&blacklist=c,d ``` - Parameters - - whitelist 白名单 - - blacklist 黑名单 -- Request body: 待插入的 JSON 数据 -- Response body data: 已创建的数据 JSON + - whitelist White list + - blacklist Black list +- Request body: JSON data to be inserted +- Response body data: Created data JSON -#### 新增用户 +#### Add a User ```bash POST /api/users:create @@ -37,7 +37,7 @@ Response 200 (application/json) } ``` -#### 新增用户文章 +#### Add a user's article ```bash POST /api/users/1/posts:create @@ -49,11 +49,11 @@ Request Body Response 200 (application/json) { - "data": {} + "data": {}, } ``` -#### Request Body 里的 association +#### Association in Request Body ```bash POST /api/posts:create @@ -86,13 +86,13 @@ POST /api/users:create?filterByTk=1&whitelist=a,b&blacklist=c,d ``` - Parameters - - whitelist 白名单 - - blacklist 黑名单 - - filterByTk 根据 tk 字段过滤,默认情况 tk 为数据表的主键 - - filter 过滤,支持 json string -- Request body: 待更新的 JSON 数据 + - whitelist White list + - blacklist Black list + - filterByTk Filter by tk field, by default tk is the primary key of the data table + - filter Filter,support json string +- Request body: JSON data to be updated -#### Request Body 里的 association +#### Association in Request Body ```bash POST /api/posts:update/1 @@ -137,3 +137,6 @@ Response 200 (application/json) ### `remove` ### `toggle` + + + diff --git a/docs/en-US/development/http-api/filter-operators.md b/docs/en-US/api/http/filter-operators.md similarity index 95% rename from docs/en-US/development/http-api/filter-operators.md rename to docs/en-US/api/http/filter-operators.md index 332f28a50d..a31112c5c5 100644 --- a/docs/en-US/development/http-api/filter-operators.md +++ b/docs/en-US/api/http/filter-operators.md @@ -1,6 +1,6 @@ # Filter operators -## 通用 +## Common - $eq - $ne @@ -37,7 +37,7 @@ ## boolean -- $isTruly +- $isTruthy - $isFalsy ## date diff --git a/docs/en-US/api/http/index.md b/docs/en-US/api/http/index.md new file mode 100644 index 0000000000..8d9323d65d --- /dev/null +++ b/docs/en-US/api/http/index.md @@ -0,0 +1,301 @@ +# Overview + +NocoBase HTTP API is designed based on Resource & Action, it is a superset of REST API. The operation is not limited to add, delete, change, and check, Resource Action can be extended arbitrarily in NocoBase. + +## Resource + +Resource has two expressions in NocoBase. + +- `` +- `.` + + + +- collection is the set of all abstract data +- association is the association data for the collection +- resource includes both collection and collection.association + + + +### Example + +- `posts` Post +- `posts.user` Post user +- `posts.tags` Post tags + +## Action + +Representing resource operations as `:` + +- `:` +- `.:` + +Built-in global operations for collection or association + +- `create` +- `get` +- `list` +- `update` +- `destroy` +- `move` + +Built-in association operation for association only + +- `set` +- `add` +- `remove` +- `toggle` + +### Example + +- `posts:create` Create posts +- `posts.user:get` View posts user +- `posts.tags:add` Attach post tags (associate existing tags with post) + +## Request URL + +```bash + /api/: + /api/:/ + /api///: + /api///:/ +``` + +### Example + +posts resource + +```bash +POST /api/posts:create +GET /api/posts:list +GET /api/posts:get/1 +POST /api/posts:update/1 +POST /api/posts:destroy/1 +``` + +posts.comments resource + +```bash +POST /api/posts/1/comments:create +GET /api/posts/1/comments:list +GET /api/posts/1/comments:get/1 +POST /api/posts/1/comments:update/1 +POST /api/posts/1/comments:destroy/1 +``` + +posts.tags resource + +```bash +POST /api/posts/1/tags:create +GET /api/posts/1/tags:get +GET /api/posts/1/tags:list +POST /api/posts/1/tags:update +POST /api/posts/1/tags:destroy +POST /api/posts/1/tags:add +GET /api/posts/1/tags:remove +``` + +## Resource location + +- collection resource, locates the data to be processed by `collectionIndex`, `collectionIndex` must be unique +- association resource, locates the data to be processed by `collectionIndex` and `associationIndex` jointly, `associationIndex` may not be unique, but `collectionIndex` and `associationIndex`'s association indexes must be unique + +When viewing association resource details, the requested URL needs to provide both `` and ``, `` is not redundant because `` may not be unique. + +For example, `tables.fields` indicates the fields of a data table + +```bash +GET /api/tables/table1/fields/title +GET /api/tables/table2/fields/title +``` + +Both table1 and table2 have a title field. The title is unique in table1, but other tables may also have a title field + +## Request parameters + +Request parameters can be placed in the request's headers, parameters (query string), and body (GET requests do not have a body). + +A few special request parameters + +- `filter` Data filtering, used in query-related operations. +- `filterByTk` filter by tk field, used in operations that specify details of the data. +- `sort` Sorting, used in query-related operations. +- `fields` which data to output, for use in query-related operations. +- `appends` additional relationship fields for use in query-related operations. +- `except` which fields to exclude (no output), used in query-related operations. +- `whitelist` fields whitelist, used in data creation and update related operations. +- `blacklist` fields blacklist, used in data creation and update related operations. + +### filter + +Data filter + +```bash +# simple +GET /api/posts?filter[status]=publish +# Recommend using the json string format, which requires encodeURIComponent encoding +GET /api/posts?filter={"status":"published"} + +# filter operators +GET /api/posts?filter[status.$eq]=publish +GET /api/posts?filter={"status.$eq":"published"} + +# $and +GET /api/posts?filter={"$and": [{"status.$eq":"published"}, {"title.$includes":"a"}]} +# $or +GET /api/posts?filter={"$or": [{"status.$eq":"pending"}, {"status.$eq":"draft"}]} + +# association field +GET /api/posts?filter[user.email.$includes]=gmail +GET /api/posts?filter={"user.email.$includes":"gmail"} +``` + +[Click here for more information about filter operators](http-api/filter-operators) + +### filterByTk + +Filter by tk field. By default + +- collection resource, tk is the primary key of the data table. +- association resource, tk is the targetKey field of the association. + +```bash +GET /api/posts:get?filterByTk=1&fields=name,title&appends=tags +``` + +### sort + +Sorting. When sorting in descending order, the fields are preceded by the minus sign `-`. + +```bash +# createAt field in ascending order +GET /api/posts:get?sort=createdAt +# createAt field descending +GET /api/posts:get?sort=-createdAt +# Multiple fields sorted jointly, createAt field descending, title A-Z ascending +GET /api/posts:get?sort=-createdAt,title +``` + +### fields + +Which fields to output + +```bash +GET /api/posts:list?fields=name,title + +Response 200 (application/json) +{ + "data": [ + { + "name": "", + "title": "" + } + ], + "meta": {} +} +``` + +### appends + +Appends a relationship field + +### except + +Which fields to exclude (not output) for use in query-related operations. + +### whitelist + +Whitelist + +```bash +POST /api/posts:create?whitelist=title + +{ + "title": "My first post", + "date": "2022-05-19" # The date field will be filtered out and will not be written to the database +} +``` + +### blacklist + +Blacklist + +```bash +POST /api/posts:create?blacklist=date + +{ + "title": "My first post", + "date": "2022-05-19" # The date field will be filtered out and will not be written to the database +} +``` + +## Request Response + +Format of the response + +```ts +type ResponseResult = { + data?: any; // Master data + meta?: any; // Additional Data + errors?: ResponseError[]; // Errors +}; + +type ResponseError = { + code?: string; + message: string; +}; +``` + +### Example + +View list + +```bash +GET /api/posts:list + +Response 200 (application/json) + +{ + data: [ + { + id: 1 + } + ], + meta: { + count: 1 + page: 1, + pageSize: 1, + totalPage: 1 + }, +} +``` + +View details + +```bash +GET /api/posts:get/1 + +Response 200 (application/json) + +{ + data: { + id: 1 + } +} +``` + +Error + +```bash +POST /api/posts:create + +Response 400 (application/json) + +{ + errors: [ + { + message: 'name must be required', + }, + ], +} +``` diff --git a/docs/en-US/api/http/javascript-sdk.md b/docs/en-US/api/http/javascript-sdk.md new file mode 100644 index 0000000000..329441c510 --- /dev/null +++ b/docs/en-US/api/http/javascript-sdk.md @@ -0,0 +1,281 @@ +# JavaScript SDK + +## APIClient + +```ts +class APIClient { + // axios instance + axios: AxiosInstance; + // constructors + constructor(instance?: AxiosInstance | AxiosRequestConfig); + // Client-side requests, support for AxiosRequestConfig and ResourceActionOptions + request, D = any>(config: AxiosRequestConfig | ResourceActionOptions): Promise; + // Get Resources + resource(name: string, of?: any): R; +} +``` + +Initialize instance + +```ts +import axios from 'axios'; +import { APIClient } from '@nocobase/sdk'; + +// Provide AxiosRequestConfig configuration parameters +const api = new APIClient({ + baseURL: 'https://localhost:8000/api', +}); + +// Provide AxiosInstance +const instance = axios.create({ + baseURL: 'https://localhost:8000/api', +}); +const api = new APIClient(instance); +``` + +## Mock + +```ts +import { APIClient } from '@nocobase/sdk'; +import MockAdapter from 'axios-mock-adapter'; + +const api = new APIClient({ + baseURL: 'https://localhost:8000/api', +}); + +const mock = new MockAdapter(api.axios); + +mock.onGet('users:get').reply(200, { + data: { id: 1, name: 'John Smith' }, +}); + +await api.request({ url: 'users:get' }); +``` + +## Storage + +APIClient uses localStorage by default, you can also custom storage. + +```ts +import { Storage } from '@nocobase/sdk'; + +class MemoryStorage extends Storage { + items = new Map(); + + clear() { + this.items.clear(); + } + + getItem(key: string) { + return this.items.get(key); + } + + setItem(key: string, value: string) { + return this.items.set(key, value); + } + + removeItem(key: string) { + return this.items.delete(key); + } +} + +const api = new APIClient({ + baseURL: 'https://localhost:8000/api', + storageClass: CustomStorage, +}); +``` + +## Auth + +```ts +// sign in and remember the current token +api.auth.signIn({ email, password }); +// sign out and delete the token +api.auth.signOut(); +// set the token +api.auth.setToken('123'); +// set the role (multiple roles) +api.auth.setRole('admin'); +// set the locale (multiple languages) +api.auth.setLocale('zh-CN'); +``` + +Custom Auth + +```ts +import { Auth } from '@nocobase/sdk'; + +class CustomAuth extends Auth { + +} + +const api = new APIClient({ + baseURL: 'https://localhost:8000/api', + authClass: CustomAuth, +}); +``` + +## Request + +```ts +// url +await api.request({ + url: 'users:list', + // request params + params: { + filter: { + 'email.$includes': 'noco', + }, + }, + // request body + data, +}); + +// resource & action +await api.request({ + resource: 'users', + action: 'list', + // action params + params: { + filter: { + 'email.$includes': 'noco', + }, + page: 1, + }, +}); +``` + +## Resource action + +```ts +await api.resource('collection')[action](); +await api.resource('collection.association', collectionId)[action](); +``` + +## Action API + +```ts +await api.resource('collection').create(); +await api.resource('collection').get(); +await api.resource('collection').list(); +await api.resource('collection').update(); +await api.resource('collection').destroy(); +await api.resource('collection.association', collectionId).create(); +await api.resource('collection.association', collectionId).get(); +await api.resource('collection.association', collectionId).list(); +await api.resource('collection.association', collectionId).update(); +await api.resource('collection.association', collectionId).destroy(); +``` + +### `get` + +```ts +interface Resource { + get: (options?: GetActionOptions) => Promise; +} + +interface GetActionOptions { + filter?: any; + filterByTk?: any; + fields?: string || string[]; + appends?: string || string[]; + expect?: string || string[]; + sort?: string[]; +} +``` + +### `list` + +```ts +interface Resource { + list: (options?: ListActionOptions) => Promise; +} + +interface ListActionOptions { + filter?: any; + filterByTk?: any; + fields?: string || string[]; + appends?: string || string[]; + expect?: string || string[]; + sort?: string[]; + page?: number; + pageSize?: number; + paginate?: boolean; +} +``` + +### `create` + +```ts +interface Resource { + create: (options?: CreateActionOptions) => Promise; +} + +interface CreateActionOptions { + whitelist?: string[]; + blacklist?: string[]; + values?: {[key: sting]: any}; +} +``` + +### `update` + +```ts +interface Resource { + update: (options?: UpdateActionOptions) => Promise; +} + +interface UpdateActionOptions { + filter?: any; + filterByTk?: any; + whitelist?: string[]; + blacklist?: string[]; + values?: {[key: sting]: any}; +} +``` + +### `destroy` + +```ts +interface Resource { + destroy: (options?: DestroyActionOptions) => Promise; +} + +interface DestroyActionOptions { + filter?: any; + filterByTk?: any; +} +``` + +### `move` + +```ts +interface Resource { + move: (options?: MoveActionOptions) => Promise; +} + +interface MoveActionOptions { + sourceId: any; + targetId?: any; + /** @default 'sort' */ + sortField?: any; + targetScope?: {[key: string]: any}; + sticky?: boolean; + method?: 'insertAfter' | 'prepend'; +} +``` + +### `` + +```ts +interface AttachmentResource { + +} + +interface UploadActionOptions { + +} + +api.resource('attachments').upload(); +api.resource('attachments').upload(); +``` diff --git a/docs/en-US/development/http-api/rest-api.md b/docs/en-US/api/http/rest-api.md similarity index 83% rename from docs/en-US/development/http-api/rest-api.md rename to docs/en-US/api/http/rest-api.md index 2d7fd86d5c..ae3d9b81a3 100644 --- a/docs/en-US/development/http-api/rest-api.md +++ b/docs/en-US/api/http/rest-api.md @@ -1,12 +1,12 @@ # REST API -NocoBase 的 HTTP API 是 REST API 的超集,标准的 CRUD API 也支持 RESTful 风格。 +NocoBase's HTTP API is a superset of the REST API, and the standard CRUD API also supports the RESTful style. -## Collection 资源 +## Collection resources --- -### 创建 collection +### Create collection HTTP API @@ -24,7 +24,7 @@ POST /api/ {} # JSON body ``` -### 查看 collection 列表 +### List collection HTTP API @@ -38,7 +38,7 @@ REST API GET /api/ ``` -### 查看 collection 详情 +### View collection details HTTP API @@ -53,7 +53,7 @@ REST API GET /api// ``` -### 更新 collection +### Update collection HTTP API @@ -62,7 +62,7 @@ POST /api/:update?filterByTk= {} # JSON body -# 或者 +# Or POST /api/:update/ {} # JSON body @@ -76,13 +76,13 @@ PUT /api// {} # JSON body ``` -### 删除 collection +### Delete collection HTTP API ```bash POST /api/:destroy?filterByTk= -# 或者 +# Or POST /api/:destroy/ ``` @@ -92,11 +92,11 @@ REST API DELETE /api// ``` -## Association 资源 +## Association resources --- -### 创建 Association +### Create Association HTTP API @@ -114,7 +114,7 @@ POST /api/// {} # JSON body ``` -### 查看 Association 列表 +### List Association HTTP API @@ -128,13 +128,13 @@ REST API GET /api/// ``` -### 查看 Association 详情 +### View Association details HTTP API ```bash GET /api///:get?filterByTk= -# 或者 +# Or GET /api///:get/ ``` @@ -144,7 +144,7 @@ REST API GET /api///:get/ ``` -### 更新 Association +### Update Association HTTP API @@ -153,7 +153,7 @@ POST /api///:update?filterByTk=//:update/ {} # JSON body @@ -164,16 +164,16 @@ REST API ```bash PUT /api///:update/ -{} # JSON 数据 +{} # JSON ``` -### 删除 Association +### Delete Association HTTP API ```bash POST /api///:destroy?filterByTk= -# 或者 +# Or POST /api///:destroy/ ``` diff --git a/docs/en-US/development/http-api/index.md b/docs/en-US/development/http-api/index.md deleted file mode 100644 index a3117cf49b..0000000000 --- a/docs/en-US/development/http-api/index.md +++ /dev/null @@ -1,301 +0,0 @@ -# 概述 - -NocoBase 的 HTTP API 基于 Resource & Action 设计,是 REST API 的超集,操作不局限于增删改查,在 NocoBase 里,Resource Action 可以任意的扩展。 - -## 资源 Resource - -在 NocoBase 里,资源(resource)有两种表达方式: - -- `` -- `.` - - - -- collection 是所有抽象数据的集合 -- association 为 collection 的关联数据 -- resource 包括 collection 和 collection.association 两类 - - - -### 示例 - -- `posts` 文章 -- `posts.user` 文章用户 -- `posts.tags` 文章标签 - -## 操作 Action - -以 `:` 的方式表示资源操作 - -- `:` -- `.:` - -内置的全局操作,可用于 collection 或 association - -- `create` -- `get` -- `list` -- `update` -- `destroy` -- `move` - -内置的关联操作,仅用于 association - -- `set` -- `add` -- `remove` -- `toggle` - -### 示例 - -- `posts:create` 创建文章 -- `posts.user:get` 查看文章用户 -- `posts.tags:add` 附加文章标签(将现有的标签与文章关联) - -## 请求 URL - -```bash - /api/: - /api/:/ - /api///: - /api///:/ -``` - -### 示例 - -posts 资源 - -```bash -POST /api/posts:create -GET /api/posts:list -GET /api/posts:get/1 -POST /api/posts:update/1 -POST /api/posts:destroy/1 -``` - -posts.comments 资源 - -```bash -POST /api/posts/1/comments:create -GET /api/posts/1/comments:list -GET /api/posts/1/comments:get/1 -POST /api/posts/1/comments:update/1 -POST /api/posts/1/comments:destroy/1 -``` - -posts.tags 资源 - -```bash -POST /api/posts/1/tags:create -GET /api/posts/1/tags:get -GET /api/posts/1/tags:list -POST /api/posts/1/tags:update -POST /api/posts/1/tags:destroy -POST /api/posts/1/tags:add -GET /api/posts/1/tags:remove -``` - -## 资源定位 - -- collection 资源,通过 `collectionIndex` 定位到待处理的数据,`collectionIndex` 必须唯一 -- association 资源,通过 `collectionIndex` 和 `associationIndex` 联合定位待处理的数据,`associationIndex` 可能不是唯一的,但是 `collectionIndex` 和 `associationIndex` 的联合索引必须唯一 - -查看 association 资源详情时,请求的 URL 需要同时提供 `` 和 ``,`` 并不多余,因为 `` 可能不是唯一的。 - -例如 `tables.fields` 表示数据表的字段 - -```bash -GET /api/tables/table1/fields/title -GET /api/tables/table2/fields/title -``` - -table1 和 table2 都有 title 字段,title 在 table1 里是唯一的,但是其他表也可能有 title 字段 - -## 请求参数 - -请求的参数可以放在 Request 的 headers、parameters(query string)、body(GET 请求没有 body) 里。 - -几个特殊的 Parameters 请求参数 - -- `filter` 数据过滤,用于查询相关操作里; -- `filterByTk` 根据 tk 字段字过滤,用于指定详情数据的操作里; -- `sort` 排序,用于查询相关操作里。 -- `fields` 输出哪些数据,用于查询相关操作里; -- `appends` 附加关系字段,用于查询相关操作里; -- `except` 排除哪些字段(不输出),用于查询相关操作里; -- `whitelist` 字段白名单,用于数据的创建和更新相关操作里; -- `blacklist` 字段黑名单,用于数据的创建和更新相关操作里; - -### filter - -数据过滤 - -```bash -# simple -GET /api/posts?filter[status]=publish -# 推荐使用 json string 的格式,需要 encodeURIComponent 编码 -GET /api/posts?filter={"status":"published"} - -# filter operators -GET /api/posts?filter[status.$eq]=publish -GET /api/posts?filter={"status.$eq":"published"} - -# $and -GET /api/posts?filter={"$and": [{"status.$eq":"published"}, {"title.$includes":"a"}]} -# $or -GET /api/posts?filter={"$or": [{"status.$eq":"pending"}, {"status.$eq":"draft"}]} - -# association field -GET /api/posts?filter[user.email.$includes]=gmail -GET /api/posts?filter={"user.email.$includes":"gmail"} -``` - -[点此查看更多关于 filter operators 的内容](http-api/filter-operators) - -### filterByTk - -根据 tk 字段过滤,默认情况: - -- collection 资源,tk 为数据表的主键; -- association 资源,tk 为 association 的 targetKey 字段。 - -```bash -GET /api/posts:get?filterByTk=1&fields=name,title&appends=tags -``` - -### sort - -排序。降序时,字段前面加上减号 `-`。 - -```bash -# createAt 字段升序 -GET /api/posts:get?sort=createdAt -# createAt 字段降序 -GET /api/posts:get?sort=-createdAt -# 多个字段联合排序,createAt 字段降序、title A-Z 升序 -GET /api/posts:get?sort=-createdAt,title -``` - -### fields - -输出哪些数据 - -```bash -GET /api/posts:list?fields=name,title - -Response 200 (application/json) -{ - "data": [ - { - "name": "", - "title": "" - } - ], - "meta": {} -} -``` - -### appends - -附加关系字段 - -### except - -排除哪些字段(不输出),用于查询相关操作里; - -### whitelist - -白名单 - -```bash -POST /api/posts:create?whitelist=title - -{ - "title": "My first post", - "date": "2022-05-19" # date 字段会被过滤掉,不会写入数据库 -} -``` - -### blacklist - -黑名单 - -```bash -POST /api/posts:create?blacklist=date - -{ - "title": "My first post", - "date": "2022-05-19" # date 字段会被过滤掉,不会写入数据库 -} -``` - -## 请求响应 - -响应的格式 - -```ts -type ResponseResult = { - data?: any; // 主体数据 - meta?: any; // 附加数据 - errors?: ResponseError[]; // 报错 -}; - -type ResponseError = { - code?: string; - message: string; -}; -``` - -### 示例 - -查看列表 - -```bash -GET /api/posts:list - -Response 200 (application/json) - -{ - data: [ - { - id: 1 - } - ], - meta: { - count: 1 - page: 1, - pageSize: 1, - totalPage: 1 - }, -} -``` - -查看详情 - -```bash -GET /api/posts:get/1 - -Response 200 (application/json) - -{ - data: { - id: 1 - }, -} -``` - -报错 - -```bash -POST /api/posts:create - -Response 400 (application/json) - -{ - errors: [ - { - message: 'name must be required', - }, - ], -} -``` \ No newline at end of file