Skip to content

Latest commit

 

History

History
538 lines (432 loc) · 46.8 KB

Document-English.md

File metadata and controls

538 lines (432 loc) · 46.8 KB

APIJSON

GitHub release Java API Android API JavaScrpit API License


Java-Server Android JavaScript Vue.js

查看中文文档

Online Test


1.About

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!



Here are some examples:

Get an User

Request:


{
  "User":{
  }
}

Click here to test

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"
}

Get an Array of Users

Request:


{
  "[]":{
    "count":3,             //just get 3 results
    "User":{
      "@column":"id,name"  //just get ids and names
    }
  }
}

Click here to test

Response:


{
  "[]":[
    {
      "User":{
        "id":38710,
        "name":"TommyLemon"
      }
    },
    {
      "User":{
        "id":70793,
        "name":"Strong"
      }
    },
    {
      "User":{
        "id":82001,
        "name":"Android"
      }
    }
  ],
  "code":200,
  "msg":"success"
}

Get an Moment and it's publisher(User)

Request:


{
  "Moment":{
  },
  "User":{
    "id@":"Moment/userId"  //User.id = Moment.userId
  }
}

Click here to test

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"
}

Get an Array of Moments

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
      }
    }
  }
}

Click here to test

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"
}

Online Test



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
   }
}
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"
       }
     }
   }
}

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":{}}},查询一个User数组。这里key和Table名都是User,User会被提取出来,即 {"User":{"id", ...}} 会被转化为 {"id", ...}
Options "key{}":[],后面是JSONArray,作为key可取的值的选项 "id{}":[38710,82001,70793],查询id符合38710,82001,70793中任意一个的一个User数组
Conditions "key{}":"条件0,条件1...",条件为任意SQL比较表达式字符串,非Number类型必须用''包含条件的值,如'a' "id{}":"<=80000,>90000",查询id符合id<=80000 | id>90000的一个User数组
Contain "key<>":Object => "key<>":[Object],key对应值的类型必须为JSONArray,Object类型不能为JSON "contactIdList<>":38710,查询contactIdList包含38710的一个User数组
Function "key()":"函数表达式",函数表达式为 function(key0,key1...),会调用后端对应的函数 function(JSONObject request, String key0, String key1...) "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"
}

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%",查询name包含"m"的一个User数组
RegEx "key?":"正则表达式" => "key?":["正则表达式"],任意正则表达式字符串,如 ^[0-9]+$ ,可用于高级搜索 "name?":"^[0-9]+$",查询name中字符全为数字的一个User数组
Alias "name:alias",name映射为alias,用alias替代name。可用于 column,Table,SQL函数 等。只用于GET类型、HEAD类型的请求 "@column":"toId:parentId",将查询的字段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",即id满足id>80000 & id<=90000

"id|{}":">90000,<=80000",同"id{}":">90000,<=80000",即id满足id>90000 | id<=80000

"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@,</Table1/key1@"
多表连接方式:
"<" - LEFT JOIN
">" - RIGHT JOIN
"&" - INNER JOIN
"|" - FULL JOIN
"!" - OUTTER JOIN
① 查询User数组,最多5个:
"count":5

② 查询第3页的User数组,每页5个:
"count":5,
"page":3


③ 查询User数组和对应的User总数:
"[]":{
   "query":2,
   "User":{}
},
"total@":"/[]/total"


④ Moment INNER JOIN User LEFT JOIN Comment:
"[]":{
   "join": "&/User/id@,</Comment/momentId@",
   "Moment":{},
   "User":{
     "name?":"t",
     "id@": "/Moment/userId"
   },
   "Comment":{
     "momentId@": "/Moment/id"
   }
}
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?"


② 只查询id,sex,name这几列并且请求结果也按照这个顺序:
"@column":"id,sex,name"

③ 查询按 name降序、id默认顺序 排序的User数组:
"@order":"name-,id"

④ 查询按userId分组的Moment数组:
"@group":"userId,id"

⑤ 查询 按userId分组、id最大值>=100 的Moment数组:
"@column":"userId,max(id)",
"@group":"userId",
"@having":"max(id)>=100"

还可以指定函数返回名:
"@column":"userId,max(id):maxId",
"@group":"userId",
"@having":"maxId>=100"


⑥ 从pictureList获取第0张图片:
"@position":0, //这里@position为自定义关键词
"firstPicture()":"getFromArray(pictureList,@position)"


4.Usage

4.1 Download and unzip APIJSON project

Clone or download > Download ZIP > Unzip to a path and remember it.

You can skip step 2 and 3, and test server response with my server IP address apijson.cn:8080.

4.2 Import MySQL table files

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.

4.3 Run Server project with Eclipse for JavaEE or IntellIJ IDEA Ultimate

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.

Eclipse for JavaEE

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

IntellIJ IDEA Ultimate

1.Import
Open > Select the path of APIJSON-Master/APIJSON(Server)/APIJSON(Idea) > OK

2.Run
Run > Run APIJSONApplication

4.4 Run Client project with ADT Bundle or Android Studio

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.

ADT Bundle

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

Android Studio

1.Import
Open an existing Android Studio project > Select the path of APIJSON-Master/APIJSON(Android)/APIJSON(AndroidStudio) > OK

2.Run
Run > Run app

4.5 Operate 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.



5.Extra

5.1 Recommend

APIJSON, 让接口和文档见鬼去吧!

仿QQ空间和微信朋友圈,高解耦高复用高灵活

3步创建APIJSON服务端新表及配置

5.2 Author

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.

5.3 Download

App
APIJSONApp.apk

Test
APIJSONTest.apk

5.4 Update

https://github.com/TommyLemon/APIJSON/commits/master

5.5 Star & Fork

https://github.com/TommyLemon/APIJSON