From 870d747dbbf677120e943e4262d5ec7e0659646c Mon Sep 17 00:00:00 2001
From: Ruoran Wang 🏆Gitee Most Valuable Project 🏆Gitee Most Valuable Project
- 中文版
- Document
- Video
+ Chinese
+ Video
Test
🚀A JSON Transmission Protocol and an ORM Library for auto providing APIs and Documents.
🚀A JSON Transmission Protocol and an ORM Library for providing APIs and Documents automatically.1.About
-APIJSON is a JSON Transmission Structure Protocol.
+APIJSON is a JSON based application that largely simplify the process of back-end API development. It allows front-end users to get data with self-defined form.
-You can set any JSON structure and request your server, and the server will response a JSON with the structure you had set.
-You can get any data by requesting server just once. It's very convenient and flexible, and does not require a special api or multiple requests.
-It provides CRUD(read and write), Fuzzy Search, Remote Function Calls, Rights Management and so on. And you can save duplicate data and improve transmission speed as well!
-
-Now you can realize JSON Transmissions without any api or document anymore!
-Client developers will no longer be suffered from various error in documents, and don't have to communicate with server developers about apis or documents anymore!
-And server developers no longer have to write new apis and documents for compatibility with legacy apps! And they will no longer be endlessly disturbed by client developers at any time!
+### Features:
+You can set any JSON structure and send a request to your server, and the server will respond JSON codes with the structure you just set.
+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 APIs with multiple requests.
+It provides CRUD(read and write), Fuzzy Search, Remote Function Calls,etc. You can save duplicate data and improve data transmission speed as well!
+APIJSON enables server developers to realize JSON transmissions without most api design or document writing anymore!
+Client developers will no longer be suffered from various errors in documents, and don't have to communicate with server developers about APIs or documents anymore!
+Server developers no longer need to worry about compatibility of APIs and documents with legacy apps! APIJSON thus helps developers reducing time in developing APIs.
From b3a4f653d0a833929bb75ee71a36af7ff48ae5a7 Mon Sep 17 00:00:00 2001
From: Ruoran Wang
delete data | base_url/delete/ | {
TableName:{
-## 4.Usage
+##
4.Getting started
+
+You can use either Eclipse for JavaEE or IntelllJ IDEA Ultimate to make installation. For both, first download the project and save it to a path.
-###
4.1 Download and unzip APIJSON project
+###
4.1 Using Eclipse to make installation
-Clone or download > Download ZIP > Unzip to a path and remember it.
+####
4.1.1 prerequisites
+
+Java Development Kit(JDK): 1.8 or above
+[MAVEN](https://maven.apache.org/download.cgi): 3.0 or above
+Mysql / Oracle
+[Eclipse Java EE IDE](https://www.eclipse.org/downloads/)for Web Developers.Version: Mars.1 Release (4.5.1)
-#### You can skip step 2 and 3, and test server response with my server IP address apijson.cn:8080.
+#### 4.1.2 Opening the project with Eclipse
+
+Open Eclipse> *File > Import > Maven > Existing Maven Projects > Next > Browse > Select the path of the project you saved / APIJSON-Java-Server / APIJSONBoot > check pom.xml...apijson-demo > Finish*
+
+####
4.1.3 Preparing the library used in demo
+
+In the menu at the right, click libs, right click apijson-orm.jar,click add as library. Apply the same to the rest *.jar* files in libs.
-###
4.2 Import MySQL table files
+####
4.1.4 Configuration
+
+Open the class named apijson.demo.server.DemoSQLConfig , then change return values of `getDBUri`,`getDBAccount`,`getDBPassword`,`getSchema` to your own database.
-This Server project needs MySQL Server and MySQLWorkbench. And you must ensure that both of them were installed.
-My config is Windows 7 + MySQL Community Server 5.7.16 + MySQLWorkbench 6.3.7 and OSX EI Capitan + MySQL Community Server 5.7.16 + MySQLWorkbench 6.3.8. The systems and softwares are all 64 bit.
+**Note**: Instead of this step, you can also [import your database](#4.2).
+
+#### 4.1.5 Running the application
-Start MySQLWorkbench > Enter a connection > Click Server menu > Data Import > Select the path of APIJSON-Master/table > Start Import > Refresh SCHEMAS, and you'll see the tables were already added.
+In Eclipse, in the menu on the top, click *Run>Run As>Java Application>choose APIJSONApplication>OK*
+###
4.2 Import MySQL table files
-###
4.3 Run Server project with Eclipse for JavaEE or IntellIJ IDEA Ultimate
+This Server project needs MySQL Server and MySQLWorkbench. Please ensure that both of them are installed.
+My config is Windows 7 + MySQL Community Server 5.7.16 + MySQLWorkbench 6.3.7 and OSX EI Capitan + MySQL Community Server 5.7.16 + MySQLWorkbench 6.3.8. Systems and softwares are all 64 bit.
-If you haven't installed any editor above, please download and install one before run.
-My config is Windows 7 + JDK 1.7.0_71 + Eclipse 4.6.1 + IntellIJ 2016.3 and OSX EI Capitan + JDK 1.8.0_91 + Eclipse 4.6.1 + IntellIJ 2016.2.5. The systems and softwares are all 64 bit.
+Start *MySQLWorkbench > Enter a connection > Click Server menu > Data Import > Select the path of APIJSON-Master/table > Start Import > Refresh SCHEMAS*, and you'll see the tables were already added.
-#### Eclipse for JavaEE
+### 4.3 Using IntellIJ IDEA Ultimate to make the installation
+
+####
4.3.1 Opening the project
-1.Import
-File > Import > Maven > Existing Maven Projects > Next > Browse > Select the path of APIJSON-Master/APIJSON(Server)/APIJSON(Eclipse_JEE) > Finish
+*Open > Select the path of the project/APIJSON-Java-Server/APIJSONBoot > OK*
-2.Run
-Run > Run As > Java Application > Select APIJSONApplication > OK
+#### 4.3.2 Preparing the library used in demo
+
+In libs, right-click *apijson-orm.jar >Add as Library>OK*. Apply this to all *.jar* files in libs.
-#### IntellIJ IDEA Ultimate
+####
4.3.3 Running the application
+
+In the menu on the top: *Run > Run > Edit Configurations > + > Application > Configuration*
+In *Main class* , choose *APIJSONApplication*;
+In *Use classpath of module* , choose *apijson-demo*.
+Click *Run* in the bottom.
-1.Import
-Open > Select the path of APIJSON-Master/APIJSON(Server)/APIJSON(Idea) > OK
+**Note**: After running, you should see APIJSON test logs and in the last, it would show ‘APIJSON已启动’. If it shows ‘address already in use’, that means port 8080 has been used . You need tochange the port. See [how to change ports for a Spring Boot Application.](https://stackoverflow.com/questions/21083170/how-to-configure-port-for-a-spring-boot-application)
-2.Run
-Run > Run APIJSONApplication
### 4.4 Run Client project with ADT Bundle or Android Studio
From b91a1a6fc0e53f099759681d1d369b724748554b Mon Sep 17 00:00:00 2001
From: Ruoran Wang
-![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_Auto_get.jpg)
-![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_Auto_code.jpg)
-![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_Auto_doc.jpg)
-![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_Auto_test.jpg)
-
-
-
-![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_App_MomentList_Circle.gif)
-![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_App_Moment_Name.gif)
-![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_App_Moment_Comment.gif)
-
-
+### Examples:
-
-
-
-### Here are some examples:
-
-#### Get an User
+#### Get a User
Request:
{
@@ -178,288 +162,9 @@ Response:
-#### Get an Moment and it's publisher(User)
-Request:
-
-
-[Click here to test](http://apijson.cn:8080/get/{"Moment":{},"User":{"id@":"Moment%252FuserId"}})
-
-Response:
-
-{
- "Moment":{
- },
- "User":{
- "id@":"Moment/userId" //User.id = Moment.userId
- }
-}
-
-
-
-{
- "Moment":{
- "id":12,
- "userId":70793,
- "date":"2017-02-08 16:06:11.0",
- "content":"1111534034"
- },
- "User":{
- "id":70793,
- "sex":0,
- "name":"Strong",
- "tag":"djdj",
- "head":"http://static.oschina.net/uploads/user/585/1170143_50.jpg?t=1390226446000",
- "contactIdList":[
- 38710,
- 82002
- ],
- "date":"2017-02-01 19:21:50.0"
- },
- "code":200,
- "msg":"success"
-}
-
-
-#### Get an Array of Moments
-Request:
-
-
-[Click here to test](http://apijson.cn:8080/get/{"[]":{"page":0,"count":2,"Moment":{"content$":"%2525a%2525"},"User":{"id@":"%252FMoment%252FuserId","@column":"id,name,head"},"Comment[]":{"count":2,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
-
-Response:
-
-{
- "[]":{ //request an Array
- "page":0, //Array condition
- "count":2,
- "Moment":{ //request an Object named Moment
- "content$":"%a%" //Object condition, search the Moments in which their contents contain 'a'
- },
- "User":{
- "id@":"/Moment/userId", //User.id = Moment.userId, reference path with it's grandfather's path omitted
- "@column":"id,name,head" //set the columns in the response
- },
- "Comment[]":{ //request an Array named Comment and extract Comments
- "count":2,
- "Comment":{
- "momentId@":"[]/Moment/id" //Comment.momentId = Moment.id, full reference path
- }
- }
- }
-}
-
-
-
-
-{
- "[]":[
- {
- "Moment":{
- "id":15,
- "userId":70793,
- "date":1486541171000,
- "content":"APIJSON is a JSON Transmission Structure Protocol…",
- "praiseUserIdList":[
- 82055,
- 82002,
- 82001
- ],
- "pictureList":[
- "http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
- "http://common.cnblogs.com/images/icon_weibo_24.png"
- ]
- },
- "User":{
- "id":70793,
- "name":"Strong",
- "head":"http://static.oschina.net/uploads/user/585/1170143_50.jpg?t=1390226446000"
- },
- "Comment[]":[
- {
- "id":176,
- "toId":166,
- "userId":38710,
- "momentId":15,
- "date":1490444883000,
- "content":"thank you"
- },
- {
- "id":1490863469638,
- "toId":0,
- "userId":82002,
- "momentId":15,
- "date":1490863469000,
- "content":"Just do it"
- }
- ]
- },
- {
- "Moment":{
- "id":58,
- "userId":90814,
- "date":1485947671000,
- "content":"This is a Content...-435",
- "praiseUserIdList":[
- 38710,
- 82003,
- 82005,
- 93793,
- 82006,
- 82044,
- 82001
- ],
- "pictureList":[
- "http://static.oschina.net/uploads/img/201604/22172507_aMmH.jpg"
- ]
- },
- "User":{
- "id":90814,
- "name":7,
- "head":"http://static.oschina.net/uploads/user/51/102723_50.jpg?t=1449212504000"
- },
- "Comment[]":[
- {
- "id":13,
- "toId":0,
- "userId":82005,
- "momentId":58,
- "date":1485948050000,
- "content":"This is a Content...-13"
- },
- {
- "id":77,
- "toId":13,
- "userId":93793,
- "momentId":58,
- "date":1485948050000,
- "content":"This is a Content...-77"
- }
- ]
- }
- ],
- "code":200,
- "msg":"success"
-}
-
-
-[Online Test](http://apijson.org)
-
-
-
-
-
-## 2.Compare with Previous HTTP Transmission Way
-
-###
2.1 Process
- Process | Previous way | APIJSON
--------- | ------------ | ------------
- Transmission | Server developers edit apis and update documents, then client developers request server and parse responses according to the documents | Client developers request server and parse responses for their requirements. No inteface! No document! No communication for any api or document between client and server developers!
- Compatibility | Server developers add new apis tagged with v2 and update documents | Nothing need to do!
-
-
-
-### 2.2 Client request
- Client request | Previous way | APIJSON
--------- | ------------ | ------------
- Requirement | Client developers append key-value pairs to an url for a request in documents | Client developers append JSON to the url for their requirements
- Structure | base_url/get/table_name?
key0=value0&key1=value1...
Only one table_name can be contained in an URL | base_url/get/
{
TableName0:{
key0:value0,
key1:value1,
...
},
TableName1:{
...
}
...
}
You can add TableNames as many as you want after an URL
- URL | Different urls for different requests. The more diffirent kinds of requests, the more different urls | One url for one method(GET,POST...), most requests use the same URL of the 7 common ones
- Key-Value Pair | key=value | key:value
-
-
-
- ### 2.3 Server operate
- Server operate | Previous way | APIJSON
--------- | ------------ | ------------
- Parse and response | Get key-value pairs and query the database with them by the default way, then encapsulate a JSON, finally return the JSON to clients | Just return what Parser#parse returned
- Way of setting JSON structure of Response | Designed in servers and cannot be modified by clients | Designed by clients and cannot be modified by servers
-
-
-
- ### 2.4 Client resolve
- Client resolve | Previous way | APIJSON
--------- | ------------ | ------------
- View structure | Search documents or view logs after responses for requests | Just view the requests, and viewing logs after responses for requests is also supported
- Operate | Parse JSON String from responses | Parse with JSONResponse or use previous way
-
-
-
-### 2.5 Requests
- Requests | Previous way | APIJSON
--------- | ------------ | ------------
- User | base_url/get/user?id=38710 | [base_url/get/
{
"User":{
"id":38710
}
}](http://apijson.cn:8080/get/{"User":{"id":38710}})
- Moment and it's publisher(User) | Request twice
Moment:
base_url/get/moment?userId=38710
User:
base_url/get/user?id=38710 | Just request once
[base_url/get/
{
"Moment":{
"userId":38710
},
"User":{
"id":38710
}
}](http://apijson.cn:8080/get/{"Moment":{"userId":38710},"User":{"id":38710}})
- User list | base_url/get/user/list?
page=0&count=3&sex=0 | [base_url/get/
{
"User[]":{
"page":0,
"count":3,
"User":{
"sex":0
}
}
}](http://apijson.cn:8080/get/{"User[]":{"page":0,"count":3,"User":{"sex":0}}})
- A list, each item contains
a Moment, a publisher(User)
and a list of top 3 Comments | The Moment must contains an User Object and a Comment Array
base_url/get/moment/list?
page=0&count=3&commentCount=3 | [base_url/get/
{
"[]":{
"page":0,
"count":3,
"Moment":{},
"User":{
"id@":"/Moment/userId"
},
"Comment[]":{
"count":3,
"Comment":{
"momentId@":"[]/Moment/id"
}
}
}
}](http://apijson.cn:8080/get/{"[]":{"page":0,"count":3,"Moment":{},"User":{"id@":"%252FMoment%252FuserId"},"Comment[]":{"count":3,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
- A list, each item contains
a Moment, the same publisher(User)
and a list of top 3 Comments | Each Moment must contains an User Object and a Comment Array
base_url/get/moment/list?
page=0&count=3
&commentCount=3&userId=38710 | Here are several ways:
① Change
"Moment":{}, "User":{"id@":"/Moment/userId"}
to
["Moment":{"userId":38710}, "User":{"id":38710}](http://apijson.cn:8080/get/{"[]":{"page":0,"count":3,"Moment":{"userId":38710},"User":{"id":38710},"Comment[]":{"count":3,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
② Or save repeated Users by this way
[base_url/get/
{
"User":{
"id":38710
},
"[]":{
"page":0,
"count":3,
"Moment":{
"userId":38710
},
"Comment[]":{
"count":3,
"Comment":{
"momentId@":"[]/Moment/id"
}
}
}
}](http://apijson.cn:8080/get/{"User":{"id":38710},"[]":{"page":0,"count":3,"Moment":{"userId":38710},"Comment[]":{"count":3,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
③ If the User is already obtained, you can also save all repeated User by this way
[base_url/get/
{
"[]":{
"page":0,
"count":3,
"Moment":{
"userId":38710
},
"Comment[]":{
"count":3,
"Comment":{
"momentId@":"[]/Moment/id"
}
}
}
}](http://apijson.cn:8080/get/{"[]":{"page":0,"count":3,"Moment":{"userId":38710},"Comment[]":{"count":3,"Comment":{"momentId@":"[]%252FMoment%252Fid"}}}})
-
-
-
- ### 2.6 Responses
- Responses | Previous way | APIJSON
--------- | ------------ | ------------
- User | {
"data":{
"id":38710,
"name":"xxx",
...
},
"code":200,
"msg":"success"
} | {
"User":{
"id":38710,
"name":"xxx",
...
},
"code":200,
"msg":"success"
}
- Moment and it's publisher(User) | Get the Moment from the first response,
and take it's userId as the value of User's id,
then send the second request to get the User
Moment:
{
"data":{
"id":235,
"content":"xxx",
...
},
"code":200,
"msg":"success"
}
User:
{
"data":{
"id":38710,
"name":"xxx",
...
},
"code":200,
"msg":"success"
} | Response only once, and no longer needs to waiting too long, relating 2 responses, switching threads and so on
{
"Moment":{
"id":235,
"content":"xxx",
...
},
"User":{
"id":38710,
"name":"xxx",
...
},
"code":200,
"msg":"success"
}
- User list | {
"data":[
{
"id":38710,
"name":"xxx",
...
},
{
"id":82001,
...
},
...
],
"code":200,
"msg":"success"
} | {
"User[]":[
{
"id":38710,
"name":"xxx",
...
},
{
"id":82001,
...
},
...
],
"code":200,
"msg":"success"
}
- A list, each item contains
a Moment, a publisher(User)
and a list of top 3 Comments | Eech Moment must contains
it's publisher(User)
and a list of top 3 Comments
{
"data":[
{
"id":235,
"content":"xxx",
...,
"User":{
...
},
"Comment":[
...
]
},
{
"id":301,
"content":"xxx",
...,
"User":{
...
},
...
},
...
],
"code":200,
"msg":"success"
} | 1.Flexible structures, you can combine the Objects and Arrays as you want
2.Loose couplings, the structure is clearer
{
"[]":[
{
"Moment":{
"id":235,
"content":"xxx",
...
},
"User":{
...
},
"Comment[]":[
...
]
},
{
"Moment":{
"id":301,
"content":"xxx",
...
},
"User":{
...
},
...
},
...
],
"code":200,
"msg":"success"
}
- A list, each item contains
a Moment, the same publisher(User)
and a list of top 3 Comments | 1.Many repeated Users, a waste of data traffic and server performance
2.Difficult to optimize since the needs of expanding apis and writing documents, and then calling the apis according to the documents
{
"data":[
{
"id":235,
"content":"xxx",
...,
"User":{
"id":38710,
"name":"Tommy"
...
},
"Comment":[
...
]
...
},
{
"id":470,
"content":"xxx",
...,
"User":{
"id":38710,
"name":"Tommy"
...
},
"Comment":[
...
]
...
},
{
"id":511,
"content":"xxx",
...,
"User":{
"id":38710,
"name":"Tommy"
...
},
"Comment":[
...
]
...
},
{
"id":595,
"content":"xxx",
...,
"User":{
"id":38710,
"name":"Tommy"
...
},
"Comment":[
...
]
...
},
...
],
"code":200,
"msg":"success"
} | Differences responses for the requests above:
① Common request
{
"[]":[
{
"Moment":{
"id":235,
"content":"xxx",
...
},
"User":{
"id":38710,
"name":"Tommy"
...
},
"Comment[]":[
...
]
},
...
],
"code":200,
"msg":"success"
}
② Save repeated Users
{
"User":{
"id":38710,
"name":"Tommy",
...
},
"[]":[
{
"Moment":{
"id":235,
"content":"xxx",
...
},
"Comment[]":[
...
]
},
...
],
"code":200,
"msg":"success"
}
③ Save all repeated Users
{
"[]":[
{
"Moment":{
"id":235,
"content":"xxx",
...
},
"Comment[]":[
...
]
},
...
],
"code":200,
"msg":"success"
}
-
-
-1.base_url指基地址,一般是顶级域名,其它分支url都是在base_url后扩展。如base_url:http://apijson.cn:8080/ ,对应的GET分支url:http://apijson.cn:8080/get/ 。下同。
-2.请求中的key或value任意一个为null值时,这个 key:value键值对 被视为无效。下同。
-3.请求中的 / 需要转义。JSONRequest.java已经用URLEncoder.encode转义,不需要再写;但如果是浏览器或Postman等直接输入url/request,需要把request中的所有 / 都改成 %252F 。下同。
-4.code,指返回结果中的状态码,200表示成功,其它都是错误码,值全部都是HTTP标准状态码。下同。
-5.msg,指返回结果中的状态信息,对成功结果或错误原因的详细说明。下同。
-6.code和msg总是在返回结果的同一层级成对出现。对所有请求的返回结果都会在最外层有一对总结式code和msg。对非GET类型的请求,返回结果里面的每个JSONObject里都会有一对code和msg说明这个JSONObject的状态。下同。
-7.id等字段对应的值仅供说明,不一定是数据库里存在的,请求里用的是真实存在的值。下同。
-
-
-
-## 3.Overview
-
-###
3.1 Operation
-
- Method | URL | Request | Response
------------- | ------------ | ------------ | ------------
-GET:
common query | base_url/get/ | {
TableName:{
…
}
}
{…}内为限制条件
例如获取一个id为235的Moment:
{
"Moment":{
"id":235
}
} | {
TableName:{
...
},
"code":200,
"msg":"success"
}
例如
{
"Moment":{
"id":235,
"userId":38710,
"content":"APIJSON,let interfaces and documents go to hell !"
},
"code":200,
"msg":"success"
}
-HEAD:
common count | base_url/head/ | {
TableName:{
…
}
}
{…}内为限制条件
例如获取一个id为38710的User所发布的Moment总数:
{
"Moment":{
"userId":38710
}
} | {
TableName:{
"code":200,
"msg":"success",
"count":10
},
"code":200,
"msg":"success"
}
例如
{
"Moment":{
"code":200,
"msg":"success",
"count":10
},
"code":200,
"msg":"success"
}
-GETS:
safe, single, simple GET | base_url/gets/ | 最外层加一个"tag":tag,其它同GET | 同GET
-HEADS:
safe, single, simple HEAD | base_url/heads/ | 最外层加一个"tag":tag,其它同HEAD | 同HEAD
-POST:
create new data | base_url/post/ | {
TableName:{
…
},
"tag":tag
}
{…}中id由服务端生成,不能传
例如一个id为38710的User发布一个新Moment:
{
"Moment":{
"userId":38710,
"content":"APIJSON,let interfaces and documents go to hell !"
},
"tag":"Moment"
} | {
TableName:{
"code":200,
"msg":"success",
"id":38710
},
"code":200,
"msg":"success"
}
例如
{
"Moment":{
"code":200,
"msg":"success",
"id":120
},
"code":200,
"msg":"success"
}
-PUT:
modify values of keys | base_url/put/ | {
TableName:{
"id":id,
…
},
"tag":tag
}
{…}中id必传
例如修改id为235的Moment的content:
{
"Moment":{
"id":235,
"content":"APIJSON,let interfaces and documents go to hell !"
},
"tag":"Moment"
} | 同POST
-DELETE:
delete data | base_url/delete/ | {
TableName:{
"id":id
},
"tag":tag
}
{…}中id必传,一般只传id
例如删除id为120的Moment:
{
"Moment":{
"id":120
},
"tag":"Moment"
} | 同POST
-
-
-1.TableName指要查询的数据库表Table的名称字符串。第一个字符为大写字母,剩下的字符要符合英语字母、数字、下划线中的任何一种。对应的值的类型为JSONObject,结构是 {...},里面放的是Table的字段(列名)。下同。
-2."tag":tag 后面的tag是非GET、HEAD请求中匹配请求的JSON结构的key,一般是要查询的table的名称,由服务端Request表中指定。下同。
-3.GET、HEAD请求是开放请求,可任意组合任意嵌套。其它请求为受限制的安全/私密请求,对应的 方法、tag、结构 都必须和 服务端Request表中所指定的 一一对应,否则请求将不被通过。下同。
-4.GETS与GET、HEADS与HEAD分别为同一类型的操作方法,请求稍有不同但返回结果相同。下同。
-5.在HTTP通信中,GET、HEAD方法一般用HTTP GET请求,其它一般用HTTP POST请求。下同。
-6.所有JSONObject都视为容器(或者文件夹),结构为 {...} ,里面可以放普通对象或子容器。下同。
-7.每个对象都有一个唯一的路径(或者叫地址),假设对象名为refKey,则用 key0/key1/.../refKey 表示。下同。
-
-
-
-### 3.2 Function
-
- Function | Key-Value | Example
------------- | ------------ | ------------
- Array | "key[]":{},后面是JSONObject,key可省略。当key和里面的Table名相同时,Table会被提取出来,即 {Table:{Content}} 会被转化为 {Content} | [{"User[]":{"User":{}}}](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{}}}),查询一个User数组。这里key和Table名都是User,User会被提取出来,即 {"User":{"id", ...}} 会被转化为 {"id", ...}
- Options | "key{}":[],后面是JSONArray,作为key可取的值的选项 | ["id{}":[38710,82001,70793]](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"id{}":[38710,82001,70793]}}}),查询id符合38710,82001,70793中任意一个的一个User数组
- Conditions | "key{}":"条件0,条件1...",条件为任意SQL比较表达式字符串,非Number类型必须用''包含条件的值,如'a' | ["id{}":"<=80000,\>90000"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"id{}":"<=80000,\>90000"}}}),查询id符合id\<=80000 \| id>90000的一个User数组
- Contain | "key<\>":Object => "key<\>":[Object],key对应值的类型必须为JSONArray,Object类型不能为JSON | ["contactIdList<\>":38710](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"contactIdList<\>":38710}}}),查询contactIdList包含38710的一个User数组
- Function | "key()":"函数表达式",函数表达式为 function(key0,key1...),会调用后端对应的函数 function(JSONObject request, String key0, String key1...) | ["isPraised()":"isContain(praiseUserIdList,userId)"](http://apijson.cn:8080/get/{"Moment":{"id":301,"isPraised()":"isContain(praiseUserIdList,userId)"}}),会调用 boolean isContain(JSONObject request, String array, String value) 函数,然后变为 "isPraised":true 这种(假设点赞用户id列表包含了userId,即这个User点了赞)
- Reference | "key@":"引用路径",引用路径为用/分隔的字符串。以/开头的是缺省引用路径,从声明key所处容器的父容器路径开始;其它是完整引用路径,从最外层开始。
被引用的refKey必须在声明key的上面。如果对refKey的容器指定了返回字段,则被引用的refKey必须写在@column对应的值内,例如 "@column":"refKey,key1,..." | ["Moment":{
"userId":38710
},
"User":{
"id@":"/Moment/userId"
}](http://apijson.cn:8080/get/{"Moment":{"userId":38710},"User":{"id@":"%252FMoment%252FuserId"}})
User内的id引用了与User同级的Moment内的userId,
即User.id = Moment.userId,请求完成后
"id@":"/Moment/userId" 会变成 "id":38710
- Search | "key$":"SQL搜索表达式" => "key$":["SQL搜索表达式"],任意SQL搜索表达式字符串,如 %key%(包含key), key%(以key开始), %k%e%y%(包含字母k,e,y) 等,%表示任意字符 | ["name$":"%m%"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name$":"%2525m%2525"}}}),查询name包含"m"的一个User数组
- RegEx | "key?":"正则表达式" => "key?":["正则表达式"],任意正则表达式字符串,如 ^[0-9]+$ ,可用于高级搜索 | ["name?":"^[0-9]+$"](http://apijson.cn:8080/get/{"User[]":{"count":3,"User":{"name%253F":"^[0-9]%252B$"}}}),查询name中字符全为数字的一个User数组
- Alias | "name:alias",name映射为alias,用alias替代name。可用于 column,Table,SQL函数 等。只用于GET类型、HEAD类型的请求 | ["@column":"toId:parentId"](http://apijson.cn:8080/get/{"Comment":{"@column":"id,toId:parentId","id":51}}),将查询的字段toId变为parentId返回
- Add | "key+":Object,Object的类型由key指定,且类型为Number,String,JSONArray中的一种。如 82001,"apijson",["url0","url1"] 等。只用于PUT请求 | "praiseUserIdList+":[82001],添加一个点赞用户id,即这个用户点了赞
- Remove | "key-":Object,与"key+"相反 | "balance-":100.00,余额减少100.00,即花费了100元
- Logic | &, \|, ! 逻辑运算符
① & 可用于"key&{}":"条件"等
② \| 可用于"key\|{}":"条件", "key\|{}":[]等,一般可省略
③ ! 可单独使用,如"key!":Object,也可像&,\|一样配合其他功能符使用 | ① ["id&{}":">80000,<=90000"](http://apijson.cn:8080/head/{"User":{"id&{}":">80000,<=90000"}}),即id满足id>80000 & id<=90000
② ["id\|{}":">90000,<=80000"](http://apijson.cn:8080/head/{"User":{"id\|{}":">90000,<=80000"}}),同"id{}":">90000,<=80000",即id满足id>90000 \| id<=80000
③ ["id!{}":[82001,38710]](http://apijson.cn:8080/head/{"User":{"id!{}":[82001,38710]}}),即id满足 ! (id=82001 \| id=38710),可过滤黑名单的消息
- Keywords in arrays | "key":Object,key为 "[]":{} 中{}内的关键词,Object的类型由key指定
① "count":Integer,查询数量,假设允许查询数组的最大数量为max(默认为100),则当count在1~max范围内时,查询count个;否则查询max个
② "page":Integer,查询页码,从0开始,一般和count一起用
③ "query":Integer,查询内容
0-对象,1-总数,2-以上全部
总数关键词为total,和query同级,通过引用赋值得到,如 "total@":"/[]/total"
这里query及total仅为GET类型的请求提供方便,一般可直接用HEAD类型的请求获取总数
④ "join":"&/Table0/key0@,\多表连接方式:
"\<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"\|" - FULL JOIN
"!" - OUTTER JOIN
| ① 查询User数组,最多5个:
["count":5](http://apijson.cn:8080/get/{"[]":{"count":5,"User":{}}})
② 查询第3页的User数组,每页5个:
["count":5,
"page":3](http://apijson.cn:8080/get/{"[]":{"count":5,"page":3,"User":{}}})
③ 查询User数组和对应的User总数:
["[]":{
"query":2,
"User":{}
},
"total@":"/[]/total"](http://apijson.cn:8080/get/{"[]":{"query":2,"count":5,"User":{}},"total@":"%252F[]%252Ftotal"})
④ Moment INNER JOIN User LEFT JOIN Comment:
["[]":{
"join": "&/User/id@,\ "Moment":{},
"User":{
"name?":"t",
"id@": "/Moment/userId"
},
"Comment":{
"momentId@": "/Moment/id"
}
}](http://apijson.org:8080/get/{"[]":{"count":5,"join":"&%252FUser%252Fid@,<%252FComment%252FmomentId@","Moment":{"@column":"id,userId,content"},"User":{"name%253F":"t","id@":"%252FMoment%252FuserId","@column":"id,name,head"},"Comment":{"momentId@":"%252FMoment%252Fid","@column":"id,momentId,content"}}})
- Keywords in objects | "@key":Object,@key为 Table:{} 中{}内的关键词,Object的类型由@key指定
① "@combine":"key0,&key1,\|key2,!key3,...", 条件组合方式
② "@column":"key0,key1...", 返回字段
③ "@order":"key0,key1+,key2-...",排序方式
④ "@group":"key0,key1,key2...",分组方式。如果@column里声明了Table的id,则id也必须在@group中声明;其它情况下必须满足至少一个条件:
1.分组的key在@column里声明
2.Table主键在@group中声明
⑤ "@having":"function0(...)?valu0,function1(...)?valu1,function2(...)?value2...",SQL函数条件,一般和@group一起用,函数一般在@column里声明
⑥ "@otherKey": Object,自定义关键词,名称和以上系统关键词不一样,且原样返回上传的值 | ① 搜索name或tag任何一个字段包含字符a的User列表:
["name?":"a",
"tag?":"a",
"@combine":"name?,tag?"](http://apijson.cn:8080/get/{"User[]":{"count":10,"User":{"@column":"id,name,tag","name%253F":"a","tag%253F":"a","@combine":"name%253F,tag%253F"}}})
② 只查询id,sex,name这几列并且请求结果也按照这个顺序:
["@column":"id,sex,name"](http://apijson.cn:8080/get/{"User":{"@column":"id,sex,name","id":38710}})
③ 查询按 name降序、id默认顺序 排序的User数组:
["@order":"name-,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"User":{"@column":"name,id","@order":"name-,id"}}})
④ 查询按userId分组的Moment数组:
["@group":"userId,id"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":%7B"@column":"userId,id","@group":"userId,id"}}})
⑤ 查询 按userId分组、id最大值>=100 的Moment数组:
["@column":"userId,max(id)",
"@group":"userId",
"@having":"max(id)>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId,max(id)","@group":"userId","@having":"max(id)>=100"}}})
还可以指定函数返回名:
["@column":"userId,max(id):maxId",
"@group":"userId",
"@having":"maxId>=100"](http://apijson.cn:8080/get/{"[]":{"count":10,"Moment":{"@column":"userId,max(id):maxId","@group":"userId","@having":"maxId>=100"}}})
⑥ 从pictureList获取第0张图片:
["@position":0, //这里@position为自定义关键词
"firstPicture()":"getFromArray(pictureList,@position)"](http://apijson.cn:8080/get/{"User":{"id":38710,"@position":0,"firstPicture()":"getFromArray(pictureList,@position)"}})
+[Test it online](http://apijson.cn/)
From 7075c389e1fe1e688cf3b9e2f0c2b03eeab4e6bf Mon Sep 17 00:00:00 2001
From: Ruoran Wang
- Chinese + Chinese Video - Test + Test
@@ -38,22 +38,11 @@
* ### [1.About](#1)
-* ### [2.Compare](#2)
-* [2.1 Process](#2.1)
-* [2.2 Client request](#2.2)
-* [2.3 Server operate](#2.3)
-* [2.4 Client resolve](#2.4)
-* [2.5 Requests](#2.5)
-* [2.6 Responses](#2.6)
-* ### [3.Overview](#3)
-* [3.1 Operation](#3.1)
-* [3.2 Function](#3.2)
-* ### [4.Usage](#4)
-* [4.1 Download and unzip](#4.1)
-* [4.2 Import tables](#4.2)
-* [4.3 Run server](#4.3)
-* [4.4 Run client](#4.4)
-* [4.4 Operate app](#4.5)
+* ### [2.Getting started](#2)
+* [2.1 Using Eclipse to make installation](#2.1)
+* [2.2 Import MySQL table files](#2.2)
+* [2.3 Using IntellIJ IDEA Ultimate to make the installation](#2.3)
+
* ### [5.Extra](#5)
* [5.1 Recommend](#5.1)
* [5.2 Author](#5.2)
@@ -170,55 +159,79 @@ Response:
-##
+@Override
+ public String getDBUri() {
+ //TODO: Change the return value to your own
+ return DATABASE_POSTGRESQL.equalsIgnoreCase(getDatabase()) ? "jdbc:postgresql://localhost:5432/postgres" : "jdbc:mysql://192.168.71.146:3306/";
+ }
+ @Override
+ public String getDBAccount() {
+ //TODO: Change the return value to your own
+ return DATABASE_POSTGRESQL.equalsIgnoreCase(getDatabase()) ? "postgres" : "root";
+ }
+ @Override
+ public String getDBPassword() {
+ //TODO: Change the return value to your own
+ return DATABASE_POSTGRESQL.equalsIgnoreCase(getDatabase()) ? null : "root";
+ }
+ @Override
+ public String getSchema() {
+ String s = super.getSchema();
+ return StringUtil.isEmpty(s, true) ? "thea" : s; //TODO: Change the return value to your own. For here,change "thea" to "your database's name"
+ }
+
-**Note**: Instead of this step, you can also [import your database](#4.2).
+**Note**: Instead of this step, you can also [import your database](#2.2).
-####
@@ -105,7 +102,6 @@ Response:
-
#### Get an Array of Users
Request:
@@ -151,11 +147,15 @@ Response:
-[Test it online](http://apijson.cn/)
+[Test it online](http://apijson.cn/)
-
+![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_Auto_get.jpg)
-## 2.Server-side deployment
+![](https://raw.githubusercontent.com/TommyLemon/StaticResources/master/APIJSON_Auto_code.jpg)
+
+
+
+
2.Server-side deployment
You can use either Eclipse for JavaEE or IntelllJ IDEA Ultimate to make installation. For both, first download the project and save it to a path.
@@ -236,8 +236,9 @@ Click *Run* in the bottom.
**Note**: After running, you should see APIJSON test logs and in the last, it would show ‘APIJSON已启动’. If it shows ‘address already in use’, that means port 8080 has been used . You need tochange the port. See [how to change ports for a Spring Boot Application.](https://stackoverflow.com/questions/21083170/how-to-configure-port-for-a-spring-boot-application)
+
-## 3. Client-side deployment
+3. Client-side deployment
### 3.1 For Android
@@ -251,10 +252,9 @@ My config: Windows 7 + JDK 1.7.0_71 + ADT Bundle 20140702 + Android Studio 2.2
* 2.Running
*Run > Run app*
-* 3. Testing
+* 3.Testing
In the browser, send a request to the server. It should return with the result.
If the default url is not available, change it to an available one, such as an IPV4 address that is running the server of the APIJSON project. Then click the request button again.
-
### 3.2 For iOS
@@ -268,7 +268,7 @@ You can use either an IDE or text editor like sublime, Atom, etc. Webstorm is re
While using a text editor, you just open the .html file in the APIJSON-JS folder.
You can also open it with Vue javascript framework. Click [here](https://vuejs.org/) to learn more.
-## 4. Contributing
+4. Contributing
We are always looking for more developers to help implementing new features, fix bugs, etc. Please have a look at the [open issues](https://github.com/APIJSON/APIJSON/issues) before opening a new one .
@@ -277,17 +277,21 @@ Fork the project and send a pull request.
Please also star the project!
-## 5. Versioning
+5. Versioning
See the latest version [here.](https://github.com/TommyLemon/APIJSON/commits/master)
-## 6. Auhtor
+
+
+6. Auhtor
Check out the author's [github account!](https://github.com/TommyLemon)to see more related projects
-If you have any questions or suggestions, you can [create an issue](https://github.com/TommyLemon/APIJSON/issues) or [send me an e-mail](mailto:tommylemon@qq.com).
+If you have any questions or suggestions, you can [create an issue](https://github.com/TommyLemon/APIJSON/issues) or [send me an e-mail](mailto:tommylemon@qq.com).
+
+
-## 7. Donating
+7. Donating
If you like this projects and want to donate for maintainance cost, or want to buy me a coffee, you can scan Wechat QR code or QQ QR code below.
From b85f350cb704bf0b286a5cfe1d97fe651ae77058 Mon Sep 17 00:00:00 2001
From: Ruoran Wang
Date: Mon, 29 Jul 2019 23:55:16 -0700
Subject: [PATCH 09/12] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E6=94=B9=E5=8F=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Document-English.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Document-English.md b/Document-English.md
index d0a5215aa..df55a3035 100644
--- a/Document-English.md
+++ b/Document-English.md
@@ -52,7 +52,7 @@
-1. About
+1. About
APIJSON is a JSON based application that largely simplify the process of back-end API development. It allows front-end users to get data with self-defined form.
@@ -61,7 +61,7 @@ APIJSON is a JSON based application that largely simplify the process of back-en
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 provides CRUD(read and write), Fuzzy Search, Remote Function Calls,etc. You can also save duplicate data and improve data transmission speed as well!
-
+#### For API design:
APIJSON largely reduces API developers' workload by reducing most api design and document writing!
With APIJSON, client developers will no longer be suffered from possible errors in documents, and don't have to communicate with server developers about APIs or documents anymore.
Server developers no longer need to worry about compatibility of APIs and documents with legacy apps.
From 849805825861c396f627f2962cbd277dcf6da92f Mon Sep 17 00:00:00 2001
From: Ruoran Wang
Date: Tue, 30 Jul 2019 23:02:43 -0700
Subject: [PATCH 10/12] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Document-English.md | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/Document-English.md b/Document-English.md
index df55a3035..fb146d421 100644
--- a/Document-English.md
+++ b/Document-English.md
@@ -52,7 +52,8 @@
-1. About
+## 1. About
+
APIJSON is a JSON based application that largely simplify the process of back-end API development. It allows front-end users to get data with self-defined form.
@@ -155,8 +156,9 @@ Response:
-
2.Server-side deployment
-
+## 2.Server-side deployment
+
+
You can use either Eclipse for JavaEE or IntelllJ IDEA Ultimate to make installation. For both, first download the project and save it to a path.
### 2.1 Installing with Eclipse
@@ -238,7 +240,7 @@ Click *Run* in the bottom.
-3. Client-side deployment
+## 3. Client-side deployment
### 3.1 For Android
@@ -268,7 +270,8 @@ You can use either an IDE or text editor like sublime, Atom, etc. Webstorm is re
While using a text editor, you just open the .html file in the APIJSON-JS folder.
You can also open it with Vue javascript framework. Click [here](https://vuejs.org/) to learn more.
-4. Contributing
+## 4. Contributing
+
We are always looking for more developers to help implementing new features, fix bugs, etc. Please have a look at the [open issues](https://github.com/APIJSON/APIJSON/issues) before opening a new one .
@@ -277,13 +280,15 @@ Fork the project and send a pull request.
Please also star the project!
-5. Versioning
+## 5. Versioning
+
See the latest version [here.](https://github.com/TommyLemon/APIJSON/commits/master)
-6. Auhtor
+## 6. Auhtor
+
Check out the author's [github account!](https://github.com/TommyLemon)to see more related projects
@@ -291,7 +296,8 @@ If you have any questions or suggestions, you can [create an issue](https://gith
-7. Donating
+## 7. Donating
+
If you like this projects and want to donate for maintainance cost, or want to buy me a coffee, you can scan Wechat QR code or QQ QR code below.
From 1d6f124b9fe0f90a3913971e306c60dc25b649a6 Mon Sep 17 00:00:00 2001
From: Ruoran Wang
Date: Tue, 30 Jul 2019 23:43:50 -0700
Subject: [PATCH 11/12] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Document-English.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/Document-English.md b/Document-English.md
index fb146d421..cced9d042 100644
--- a/Document-English.md
+++ b/Document-English.md
@@ -52,8 +52,8 @@
-## 1. About
-
+1. About
+
APIJSON is a JSON based application that largely simplify the process of back-end API development. It allows front-end users to get data with self-defined form.
@@ -156,7 +156,7 @@ Response:
-##
2.Server-side deployment
+2.Server-side deployment
You can use either Eclipse for JavaEE or IntelllJ IDEA Ultimate to make installation. For both, first download the project and save it to a path.
@@ -240,7 +240,7 @@ Click *Run* in the bottom.
-## 3. Client-side deployment
+3. Client-side deployment
### 3.1 For Android
@@ -270,7 +270,7 @@ You can use either an IDE or text editor like sublime, Atom, etc. Webstorm is re
While using a text editor, you just open the .html file in the APIJSON-JS folder.
You can also open it with Vue javascript framework. Click [here](https://vuejs.org/) to learn more.
-## 4. Contributing
+4. Contributing
We are always looking for more developers to help implementing new features, fix bugs, etc. Please have a look at the [open issues](https://github.com/APIJSON/APIJSON/issues) before opening a new one .
@@ -280,14 +280,14 @@ Fork the project and send a pull request.
Please also star the project!
-## 5. Versioning
+5. Versioning
See the latest version [here.](https://github.com/TommyLemon/APIJSON/commits/master)
-## 6. Auhtor
+6. Auhtor
Check out the author's [github account!](https://github.com/TommyLemon)to see more related projects
@@ -296,7 +296,7 @@ If you have any questions or suggestions, you can [create an issue](https://gith
-## 7. Donating
+7. Donating
If you like this projects and want to donate for maintainance cost, or want to buy me a coffee, you can scan Wechat QR code or QQ QR code below.
From 1c3f6f61d70acc521177e296b5b1c71380b0abe6 Mon Sep 17 00:00:00 2001
From: Ruoran Wang
Date: Wed, 31 Jul 2019 00:17:15 -0700
Subject: [PATCH 12/12] fix typo
---
Document-English.md | 37 ++++++++++++++++---------------------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/Document-English.md b/Document-English.md
index cced9d042..f5ac05fb2 100644
--- a/Document-English.md
+++ b/Document-English.md
@@ -52,19 +52,19 @@
-1. About
-
+## 1. About
-APIJSON is a JSON based application that largely simplify the process of back-end API development. It allows front-end users to get data with self-defined form.
+APIJSON is a JSON based internet communication protocol and an ORM library that largely simplifies the process of back-end API development. It also allows users to get data more quickly with self-defined form and fewer endpoints requests.
### Features:
#### 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 provides CRUD(read and write), Fuzzy Search, Remote Function Calls,etc. You can also save duplicate data and improve data transmission speed as well!
+It provides CRUD(read and write), Fuzzy Search, Remote Function Calls,etc. You can also save duplicate data, see request history,etc.
+
#### For API design:
-APIJSON largely reduces API developers' workload by reducing most api design and document writing!
-With APIJSON, client developers will no longer be suffered from possible errors in documents, and don't have to communicate with server developers about APIs or documents anymore.
+APIJSON largely reduces API developers' workload by reducing most api design and documentation work.
+With APIJSON, client developers will no longer be suffered from possible errors in documents, and it saves communication between server developers and client developers about APIs or documentations .
Server developers no longer need to worry about compatibility of APIs and documents with legacy apps.
### Examples:
@@ -156,9 +156,8 @@ Response:
-
2.Server-side deployment
-
-
+## 2.Server-side deployment
+
You can use either Eclipse for JavaEE or IntelllJ IDEA Ultimate to make installation. For both, first download the project and save it to a path.
### 2.1 Installing with Eclipse
@@ -240,7 +239,7 @@ Click *Run* in the bottom.
-3. Client-side deployment
+## 3. Client-side deployment
### 3.1 For Android
@@ -270,35 +269,31 @@ You can use either an IDE or text editor like sublime, Atom, etc. Webstorm is re
While using a text editor, you just open the .html file in the APIJSON-JS folder.
You can also open it with Vue javascript framework. Click [here](https://vuejs.org/) to learn more.
-4. Contributing
-
+## 4. Contributing
We are always looking for more developers to help implementing new features, fix bugs, etc. Please have a look at the [open issues](https://github.com/APIJSON/APIJSON/issues) before opening a new one .
Fork the project and send a pull request.
-Please also star the project!
+Please also ⭐Star the project!
-5. Versioning
-
+## 5. Versioning
See the latest version [here.](https://github.com/TommyLemon/APIJSON/commits/master)
-6. Auhtor
-
+## 6. Auhtor
-Check out the author's [github account!](https://github.com/TommyLemon)to see more related projects
+Check out the author's [github account](https://github.com/TommyLemon)to see more related projects.
If you have any questions or suggestions, you can [create an issue](https://github.com/TommyLemon/APIJSON/issues) or [send me an e-mail](mailto:tommylemon@qq.com).
-7. Donating
-
-
+## 7. Donating
+
If you like this projects and want to donate for maintainance cost, or want to buy me a coffee, you can scan Wechat QR code or QQ QR code below.