From 66b53c6883ae1be9e7970d8d15fb229fef17e3ed Mon Sep 17 00:00:00 2001 From: Hamid Zare <12127420+hamidzr@users.noreply.github.com> Date: Thu, 29 Oct 2026 15:15:48 -0500 Subject: [PATCH 1/2] Fix typos in documentation Signed-off-by: Hamid Zare <12127420+hamidzr@users.noreply.github.com> --- Document.md | 6 +++--- README.md | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Document.md b/Document.md index f0833f26..22b81447 100644 --- a/Document.md +++ b/Document.md @@ -313,13 +313,13 @@ Response:
-### 2. Keyswords in URL parameters +### 2. Keywords in URL parameters Functions | Key-value pairs | Examples ------------ | ------------ | ------------ Get data in arrays | `"key[]":{}`
The part after the colon is a JSONObject. *key* is optional. When *key* is the same as the table name , the JSONObject will be in a simplified form. For example, `{Table:{Content}}` will be written as `{Content}`.| [{"User[]":{"User":{}}}](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{}}})
It is used for getting data from a user. Here, key and tablename are all "User", then
`{"User":{"id", ...}}`
will be written as
`{"id", ...}` Get data that meets specific conditions | `"key{}":[]`
The part after the colon is a JSONArray with conditions inside.| ["id{}":[38710,82001,70793]](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"id{}":[38710,82001,70793]}}})
In SQL, this would be `id IN(38710,82001,70793)`.
It means getting data with id equals 38710,82001,70793. - Get data with comparison operation| `"key{}":"condition0,condition1..."`
Conditions can be any SQL comparision operation. Use''to include any non-number characters.| ["id{}":"<=80000,\>90000"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"id{}":"<=80000,\>90000"}}})
In SQL, it'd be
`id<=80000 OR id>90000`,
which means get User array with id\<=80000 \| id>90000 + Get data with comparison operation| `"key{}":"condition0,condition1..."`
Conditions can be any SQL comparison operation. Use''to include any non-number characters.| ["id{}":"<=80000,\>90000"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"id{}":"<=80000,\>90000"}}})
In SQL, it'd be
`id<=80000 OR id>90000`,
which means get User array with id\<=80000 \| id>90000 Get data that contains an element | `"key<>":Object` => `"key<>":[Object]`
*key* must be a JSONArray while *Object* cannot be JSON.| ["contactIdList<\>":38710](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"contactIdList<\>":38710}}})
In SQL, this would be
`json_contains(contactIdList,38710)`.
It means find data of the User whose contactList contains 38710. See if it exists |`"key}{@":{`
   `"from":"Table",`
   `"Table":{ ... }`
`}`

}{ means EXISTS.
*key* is the one you want to check.
Here is a *Subquery* in it, see specifications below for more information. | ["id}{@":{
   "from":"Comment",
   "Comment":{
      "momentId":15
   }
}](http://apijson.cn:8080/get/{"User":{"id}{@":{"from":"Comment","Comment":{"momentId":15}}}})
WHERE EXISTS(SELECT * FROM Comment WHERE momentId=15) Include functions in parameters | `"key()":"function (key0,key1...)"`
This will trigger the back-end
`function(JSONObject request, String key0, String key1...)`
to get or testify data.
Use - and + to show the order of priority: analyze key-() > analyze the current object > analyze key() > analyze child object > analyze key+()| ["isPraised()":"isContain(praiseUserIdList,userId)"](http://apijson.cn:8080/get/{"Moment":{"id":301,"isPraised()":"isContain(praiseUserIdList,userId)"}})
This will use function boolean isContain(JSONObject request, String array, String value). In this case, client will get "isPraised":true(In this case, client use function to testify if a user clicked ‘like’ button for a Moment.) @@ -329,7 +329,7 @@ Response: Regular Expression| `"key~":"regular expression"` => `"key~":["regular expression"]`
It can be any regular expressions.Eg. ^[0-9]+$ ,*~ not case sensitive, advanced search is applicable.| ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}})
In SQL, it's
`name REGEXP '^[0-9]+$'`. Get data in a range| `"key%":"start,end"` => `"key%":["start,end"]`
The data type of start and end can only be either Boolean, Number or String. Eg. "2017-01-01,2019-01-01" ,["1,90000", "82001,100000"]. It's used for getting data from a specific time range. | ["date%":"2017-10-01,2018-10-01"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018-10-01"}}})
In SQL, it's
`date BETWEEN '2017-10-01' AND '2018-10-01'`,
meaning to get User data that registered between 2017-10-01 and 2018-10-01. Make an alias | `"name:alias"`
this changes name to alias in returning results. It’s applicable to column, tableName, SQL Functions, etc. but only in GET, HEAD requests. | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}})
In SQL, it's
`toId AS parentId`.
It'll return `parentId` instead of `toId`.

For @key format like "lc_wai6b3vk2:(lc_wai6b3vk)", it means renaming field lc_wai6b3vk2 to lc_wai6b3vk, commonly used for field renaming scenarios. Example:
{
  "lc_sinan_ba074fbb": {
    "lc_wai6b3vk": "11",
    "lc_wai6b3vk2": "22",
    "@combine": "lc_wai6b3vk \\| lc_wai6b3vk2",
    "@key": "lc_wai6b3vk2:(lc_wai6b3vk)"
  }
}
corresponds to SQL `(lc_wai6b3vk = '11' OR lc_wai6b3vk2 = '22')`, but the lc_wai6b3vk2 field will be renamed and displayed as lc_wai6b3vk in the returned result - Add / expand an item | `"key+":Object`
The type of Object is decided by *key*. Types can be Number, String, JSONArray. Froms are 82001,"apijson",["url0","url1"] respectively. It’s only applicable to PUT request.| "praiseUserIdList+":[82001]. In SQL, it's
`json_insert(praiseUserIdList,82001)`.
Add an *id* that praised the Moment. + Add / expand an item | `"key+":Object`
The type of Object is decided by *key*. Types can be Number, String, JSONArray. Forms are 82001,"apijson",["url0","url1"] respectively. It’s only applicable to PUT request.| "praiseUserIdList+":[82001]. In SQL, it's
`json_insert(praiseUserIdList,82001)`.
Add an *id* that praised the Moment. Delete / decrease an item | `"Key-":Object`
It’s the contrary of "key+" | "balance-":100.00. In SQL, it's
`balance = balance - 100.00`,
meaning there's 100 less in balance. Operations | &, \|, !
They're used in logic operations. It’s the same as AND, OR, NOT in SQL respectively.
By default, for the same key, it’s ‘\|’ (OR)operation among conditions; for different keys, the default operation among conditions is ‘&’(AND).
| ① ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"User":{"id&{}":">80000,<=90000"}})
In SQL, it's
`id>80000 AND id<=90000`,
meaning *id* needs to be id>80000 & id<=90000

② ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"User":{"id\|{}":">90000,<=80000"}})
It's the same as "id{}":">90000,<=80000".
In SQL, it's
`id>80000 OR id<=90000`,
meaning that *id* needs to be id>90000 \| id<=80000

③ ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}})
In SQL, it's
`id NOT IN(82001,38710)`,
meaning id needs to be ! (id=82001 \| id=38710). Keywords in an Array: It can be self-defined. | As for `"key":Object`, *key* is the keyword of *{}* in *"[]":{}*. The type of *Object* is up to *key*.

① `"count":Integer` It's used to count the number. The default largest number is 100.

② `"page":Integer` It’s used for getting data from which page, starting from 0. The default largest number is 100. It’s usually used with COUNT.

③ `"query":Integer` Get the number of items that match conditions
When to get the object, the integer should be 0; when to get the total number, it’s 1; when both above, it’s 2.
You can get the total number with keyword total. It can be referred to other values.
Eg.
`"total@":"/[]/total"`
Put it as the same level of query.
*Query* and *total* are used in GET requests just for convenience. Generally, HEAD request is for getting numbers like the total number.

④ `"join":"&/Table0,Join tables:
"\<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"\|" - FULL JOIN
"!" - OUTER JOIN
"@" - APP JOIN
Where @ APP JOIN is in application layer.It’ll get all the keys in tables that refKeys in result tables are referred to, like refKeys:[value0, value1….]. Then, as the results get data according to `key=$refKey` a number of times (COUNT), it uses key `IN($refKeys)` to put these counts together in just one SQL query, in order to improve the performance.
Other JOIN functions are the same as those in SQL.
`"join":"`"MainTable":{},`
`"ViceTable":{"key@":"/MainTable/refKey"}`
will return
`MainTable LEFT JOIN ViceTable`
`ON ViceTable.key=MainTable.refKey`

⑤ `"otherKey":Object` Self-defined keyword other than those that already in the system. It also returns with self-defined keywords.| ① Get User arrays with maximum of 5:
["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})

② Look into User arrays on page 3. Show 5 of them each page.
["count":5,
"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})

③ Get User Arrays and count the total number of Users:
["[]":{
   "query":2,
   "User":{}
},
"total@":"/[]/total"](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal"})
Questions like total page numbers or if there's next page can be solved by total,count,page functions,
Total page number:
`int totalPage = Math.ceil(total / count)`
If this is the last page:
`boolean hasNextPage = total > count*page`
If this is the first page:
`boolean isFirstPage = page <= 0`
If it's the last page:
`boolean isLastPage = total <= count*page`
...

④ Moment INNER JOIN User LEFT JOIN Comment:
["[]":{
   "join": "&/User,\    "Moment":{},
   "User":{
     "name~":"t",
     "id@": "/Moment/userId"
   },
   "Comment":{
     "momentId@": "/Moment/id"
   }
}](http://apijson.cn:8080/get/{"[]":{"count":5,"join":"&%252FUser,\<%252FComment","Moment":{"@column":"id,userId,content"},"User":{"name~":"t","id@":"%252FMoment%252FuserId","@column":"id,name,head"},"Comment":{"momentId@":"%252FMoment%252Fid","@column":"id,momentId,content"}}})

⑤ Add the current user to every level:
["User":{},
"[]":{
   "name@":"User/name", //self-defined keyword
   "Moment":{}
}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}}) diff --git a/README.md b/README.md index acda59c5..f5648039 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ It also allows users to get data more quickly with self-defined form and fewer e #### For getting data: You can get any data by defining the specific information you want and send it to the server.
You can get different types of data by making just one request to the server.
-It's very convenient and flexible, and dosen't require different API endpoints with multiple requests.
+It's very convenient and flexible, and doesn't require different API endpoints with multiple requests.
It provides CRUD(read and write), Fuzzy Search, Remote Function Calls, etc.
You can also save duplicate data, see request history, etc.
@@ -346,8 +346,8 @@ If you have any questions or suggestions, you can [create an issue](https://gith [More APIJSON Users](https://github.com/APIJSON/APIJSON/issues/73) -### Contributers of APIJSON: -[Contributers](/CONTRIBUTING.md) for the APIJSON core project(7 Tencent engineers, 1 Microsoft engineer, 1 Zhihu architect, 1 Bytedance(TikTok) engineer, 1 NetEase engineer, 1 Zoom engineer, 1 YTO Express engineer, 1 Zhilian engineer, 1 UC student、3 SUSTech students, etc.):
+### Contributors of APIJSON: +[Contributors](/CONTRIBUTING.md) for the APIJSON core project(7 Tencent engineers, 1 Microsoft engineer, 1 Zhihu architect, 1 Bytedance(TikTok) engineer, 1 NetEase engineer, 1 Zoom engineer, 1 YTO Express engineer, 1 Zhilian engineer, 1 UC student、3 SUSTech students, etc.):

Screenshot 2026-04-18 at 05 28 48 @@ -365,7 +365,7 @@ https://search.gitee.com/?skin=rec&type=repository&q=apijson&sort=stars_count
-Thanks to all contributers of APIJSON! +Thanks to all contributors of APIJSON!
@@ -383,7 +383,7 @@ APIJSON was shown as a top open source Java projects on OSS Compass [#518](https ### Ecosystem [APIJSON-Demo](https://github.com/APIJSON/APIJSON-Demo) Demo projects with document and SQL files for APIJSON with different programming languages and different frameworks -[A2API](https://github.com/TommyLemon/A2API) AI generate UI once, API view/edit data everytime safely, quickly and stably. Chat agent to HTTP API to safely, quickly and stably add, view, edit or remove data in tables, forms or charts together with A2UI. +[A2API](https://github.com/TommyLemon/A2API) AI generate UI once, API view/edit data every time safely, quickly and stably. Chat agent to HTTP API to safely, quickly and stably add, view, edit or remove data in tables, forms or charts together with A2UI. [apijson-orm](https://github.com/APIJSON/apijson-orm) APIJSON ORM library, Maven, Gradle, etc can be used for dependencies @@ -471,7 +471,7 @@ APIJSON was shown as a top open source Java projects on OSS Compass [#518](https [SpringServer1.2-APIJSON](https://github.com/Airforce-1/SpringServer1.2-APIJSON) The smart Party building server provides interfaces for uploading and downloading files -[apijson_template](https://github.com/abliger/apijson_template) APIJSON Java template, using Gradle to manage dependencie and building apps +[apijson_template](https://github.com/abliger/apijson_template) APIJSON Java template, using Gradle to manage dependency and building apps [api-json-demo](https://gitee.com/hxdwd/api-json-demo) Demo for APIJSON to replace traditional ORM, compated Oracle transactions From 18e5e6b2caf9ffc8993562ac9432b7ad2cab9cb5 Mon Sep 17 00:00:00 2001 From: Hamid Zare <12127420+hamidzr@users.noreply.github.com> Date: Thu, 29 Oct 2026 15:17:13 -0500 Subject: [PATCH 2/2] Keep original wording in Document.md Signed-off-by: Hamid Zare <12127420+hamidzr@users.noreply.github.com> --- Document.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Document.md b/Document.md index 22b81447..49e6dd3d 100644 --- a/Document.md +++ b/Document.md @@ -329,7 +329,7 @@ Response: Regular Expression| `"key~":"regular expression"` => `"key~":["regular expression"]`
It can be any regular expressions.Eg. ^[0-9]+$ ,*~ not case sensitive, advanced search is applicable.| ["name~":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name~":"^[0-9]%252B$"}}})
In SQL, it's
`name REGEXP '^[0-9]+$'`. Get data in a range| `"key%":"start,end"` => `"key%":["start,end"]`
The data type of start and end can only be either Boolean, Number or String. Eg. "2017-01-01,2019-01-01" ,["1,90000", "82001,100000"]. It's used for getting data from a specific time range. | ["date%":"2017-10-01,2018-10-01"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"date%2525":"2017-10-01,2018-10-01"}}})
In SQL, it's
`date BETWEEN '2017-10-01' AND '2018-10-01'`,
meaning to get User data that registered between 2017-10-01 and 2018-10-01. Make an alias | `"name:alias"`
this changes name to alias in returning results. It’s applicable to column, tableName, SQL Functions, etc. but only in GET, HEAD requests. | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}})
In SQL, it's
`toId AS parentId`.
It'll return `parentId` instead of `toId`.

For @key format like "lc_wai6b3vk2:(lc_wai6b3vk)", it means renaming field lc_wai6b3vk2 to lc_wai6b3vk, commonly used for field renaming scenarios. Example:
{
  "lc_sinan_ba074fbb": {
    "lc_wai6b3vk": "11",
    "lc_wai6b3vk2": "22",
    "@combine": "lc_wai6b3vk \\| lc_wai6b3vk2",
    "@key": "lc_wai6b3vk2:(lc_wai6b3vk)"
  }
}
corresponds to SQL `(lc_wai6b3vk = '11' OR lc_wai6b3vk2 = '22')`, but the lc_wai6b3vk2 field will be renamed and displayed as lc_wai6b3vk in the returned result - Add / expand an item | `"key+":Object`
The type of Object is decided by *key*. Types can be Number, String, JSONArray. Forms are 82001,"apijson",["url0","url1"] respectively. It’s only applicable to PUT request.| "praiseUserIdList+":[82001]. In SQL, it's
`json_insert(praiseUserIdList,82001)`.
Add an *id* that praised the Moment. + Add / expand an item | `"key+":Object`
The type of Object is decided by *key*. Types can be Number, String, JSONArray. Froms are 82001,"apijson",["url0","url1"] respectively. It’s only applicable to PUT request.| "praiseUserIdList+":[82001]. In SQL, it's
`json_insert(praiseUserIdList,82001)`.
Add an *id* that praised the Moment. Delete / decrease an item | `"Key-":Object`
It’s the contrary of "key+" | "balance-":100.00. In SQL, it's
`balance = balance - 100.00`,
meaning there's 100 less in balance. Operations | &, \|, !
They're used in logic operations. It’s the same as AND, OR, NOT in SQL respectively.
By default, for the same key, it’s ‘\|’ (OR)operation among conditions; for different keys, the default operation among conditions is ‘&’(AND).
| ① ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"User":{"id&{}":">80000,<=90000"}})
In SQL, it's
`id>80000 AND id<=90000`,
meaning *id* needs to be id>80000 & id<=90000

② ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"User":{"id\|{}":">90000,<=80000"}})
It's the same as "id{}":">90000,<=80000".
In SQL, it's
`id>80000 OR id<=90000`,
meaning that *id* needs to be id>90000 \| id<=80000

③ ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}})
In SQL, it's
`id NOT IN(82001,38710)`,
meaning id needs to be ! (id=82001 \| id=38710). Keywords in an Array: It can be self-defined. | As for `"key":Object`, *key* is the keyword of *{}* in *"[]":{}*. The type of *Object* is up to *key*.

① `"count":Integer` It's used to count the number. The default largest number is 100.

② `"page":Integer` It’s used for getting data from which page, starting from 0. The default largest number is 100. It’s usually used with COUNT.

③ `"query":Integer` Get the number of items that match conditions
When to get the object, the integer should be 0; when to get the total number, it’s 1; when both above, it’s 2.
You can get the total number with keyword total. It can be referred to other values.
Eg.
`"total@":"/[]/total"`
Put it as the same level of query.
*Query* and *total* are used in GET requests just for convenience. Generally, HEAD request is for getting numbers like the total number.

④ `"join":"&/Table0,Join tables:
"\<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"\|" - FULL JOIN
"!" - OUTER JOIN
"@" - APP JOIN
Where @ APP JOIN is in application layer.It’ll get all the keys in tables that refKeys in result tables are referred to, like refKeys:[value0, value1….]. Then, as the results get data according to `key=$refKey` a number of times (COUNT), it uses key `IN($refKeys)` to put these counts together in just one SQL query, in order to improve the performance.
Other JOIN functions are the same as those in SQL.
`"join":"`"MainTable":{},`
`"ViceTable":{"key@":"/MainTable/refKey"}`
will return
`MainTable LEFT JOIN ViceTable`
`ON ViceTable.key=MainTable.refKey`

⑤ `"otherKey":Object` Self-defined keyword other than those that already in the system. It also returns with self-defined keywords.| ① Get User arrays with maximum of 5:
["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})

② Look into User arrays on page 3. Show 5 of them each page.
["count":5,
"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})

③ Get User Arrays and count the total number of Users:
["[]":{
   "query":2,
   "User":{}
},
"total@":"/[]/total"](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal"})
Questions like total page numbers or if there's next page can be solved by total,count,page functions,
Total page number:
`int totalPage = Math.ceil(total / count)`
If this is the last page:
`boolean hasNextPage = total > count*page`
If this is the first page:
`boolean isFirstPage = page <= 0`
If it's the last page:
`boolean isLastPage = total <= count*page`
...

④ Moment INNER JOIN User LEFT JOIN Comment:
["[]":{
   "join": "&/User,\    "Moment":{},
   "User":{
     "name~":"t",
     "id@": "/Moment/userId"
   },
   "Comment":{
     "momentId@": "/Moment/id"
   }
}](http://apijson.cn:8080/get/{"[]":{"count":5,"join":"&%252FUser,\<%252FComment","Moment":{"@column":"id,userId,content"},"User":{"name~":"t","id@":"%252FMoment%252FuserId","@column":"id,name,head"},"Comment":{"momentId@":"%252FMoment%252Fid","@column":"id,momentId,content"}}})

⑤ Add the current user to every level:
["User":{},
"[]":{
   "name@":"User/name", //self-defined keyword
   "Moment":{}
}](http://apijson.cn:8080/get/{"User":{},"[]":{"name@":"User%252Fname","Moment":{}}})