Java-Server Android JavaScript
APIJSON is a JSON Transmission Structure Protocol.
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!
Request:
{
"User":{
}
}
Response:
{
"User":{
"id":38710,
"sex":0,
"name":"TommyLemon",
"certified":true,
"tag":"Android&Java",
"phone":13000038710,
"head":"http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
"date":1485948110000,
"pictureList":[
"http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
"http://common.cnblogs.com/images/icon_weibo_24.png"
]
},
"code":200,
"msg":"success"
}
Request:
{
"[]":{
"count":3, //just get 3 results
"User":{
"@column":"id,name" //just get ids and names
}
}
}
Response:
{
"[]":[
{
"User":{
"id":38710,
"name":"TommyLemon"
}
},
{
"User":{
"id":70793,
"name":"Strong"
}
},
{
"User":{
"id":82001,
"name":"Android"
}
}
],
"code":200,
"msg":"success"
}
Request:
{
"Moment":{
},
"User":{
"id@":"Moment/userId" //User.id = Moment.userId
}
}
Response:
{
"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"
}
Request:
{
"[]":{ //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
}
}
}
}
Response:
{
"[]":[
{
"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"
}
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! |
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 |
Server operation | 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 |
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 |
Client requests | Previous way | APIJSON |
---|---|---|
User | base_url/get/user?id=38710 | base_url/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 } } |
User list | base_url/get/user/list? page=0&count=3&sex=0 |
base_url/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" } } } } |
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} ② 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" } } } } ③ 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" } } } } |
Server 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" } |
Clone or download > Download ZIP > Unzip to a path and remember it.
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.
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.
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.
1.Import
File > Import > Maven > Existing Maven Projects > Next > Browse > Select the path of APIJSON-Master/APIJSON(Server)/APIJSON(Eclipse_JEE) > Finish
2.Run
Run > Run As > Java Application > Select APIJSONApplication > OK
1.Import
Open > Select the path of APIJSON-Master/APIJSON(Server)/APIJSON(Idea) > OK
2.Run
Run > Run APIJSONApplication
You can skip this step and download the Client App below.
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 + ADT Bundle 20140702 + Android Studio 2.2 and OSX EI Capitan + (JDK 1.7.0_71 + ADT Bundle 20140702) + (JDK 1.8.0_91 + Android Studio 2.1.2). The systems and softwares are all 64 bit.
1.Import
File > Import > Android > Existing Android Code Into Workspace > Next > Browse > Select the path of APIJSON-Master/APIJSON(Android)/APIJSON(ADT) > Finish
2.Run
Run > Run As > Android Application
1.Import
Open an existing Android Studio project > Select the path of APIJSON-Master/APIJSON(Android)/APIJSON(AndroidStudio) > OK
2.Run
Run > Run app
Select an APIJSON request to send to server and wait. It will show the result received.
If the default url is not available, change it to an available one, such as an IPV4 address of a computer running APIJSON Server project. Then click the Query button to request again.
App
APIJSONApp.apk
Test
APIJSONTest.apk
TommyLemon:https://github.com/TommyLemon
If you have any questions or suggestions, you can create an issue or send me an e-mail.
If you fixed some bugs or added some functions, I would greatly appreciate it if you contribute your code.