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

作者: 孤独的探索号 | 来源:发表于2016-12-14 19:42 被阅读1624次

<h3><strong>我:</strong></h3>

<p>APIJSON,让接口和文档见鬼去吧!</p>
<p><a href="https://github.com/TommyLemon/APIJSON">https://github.com/TommyLemon/APIJSON</a></p>

<p>

</p>

<p><a href="https://github.com/TommyLemon/APIJSON">https://github.com/TommyLemon/APIJSON</a></p>

<h3><strong>服务端:</strong></h3>

<p>什么鬼?</p>

<h3><strong>客户端:</strong></h3>

<p>APIJSON是啥?</p>

<h3><strong>我:</strong></h3>

<p>APIJSON是一种JSON传输结构协议。</p>

<p>客户端可以定义任何JSON结构去向服务端发起请求,服务端就会返回对应结构的JSON字符串,所求即所得。</p>

<p>一次请求任意结构任意数据,方便灵活,不需要专门接口或多次请求。</p>

<p>支持增删改查、模糊搜索、远程函数调用等。还能去除重复数据,节省流量提高速度!</p>

<p>从此HTTP传输JSON数据没有接口,更不需要文档!</p>

<p>客户端再也不用和服务端沟通接口或文档问题了!再也不会被文档各种错误坑了!</p>

<p>服务端再也不用为了兼容旧版客户端写新版接口和文档了!再也不会被客户端随时随地没完没了地烦了!</p>

<p>


</p>

<p>

</p>

<p>

</p>

<p>

</p>

<p>

</p>

<p>

</p>

<p> </p>

<h3><strong>客户端:</strong></h3>

<p>这个APIJSON有这么好?怎么做到的?</p>

<h3><strong>我:</strong></h3>

<p>举个栗子(查询类似微信朋友圈的动态列表):</p>

<p>请求:</p>

<pre>
{
"[]": { //请求一个array
"page": 0, //array条件
"count": 2,
"User": { //请求查询名为User的table,返回名为User的JSONObject
"sex": 0 //object条件
},
"Moment": {
"userId@": “/User/id” //缺省依赖路径,从同级object的路径开始
},
"Comment[]": { //请求一个名为Comment的array
"page": 0,
"count": 2,
"Comment": {
"momentId@": “[]/Moment/id” //完整依赖路径
}
}
}
}</code></pre>

<p><a href="http://139.196.140.118:8080/get/%7B%22%5B%5D%22%3A%7B%22User%22%3A%7B%22sex%22%3A0%7D%2C%22Moment%22%3A%7B%22userId%40%22%3A%22%252FUser%252Fid%22%7D%2C%22Comment%5B%5D%22%3A%7B%22Comment%22%3A%7B%22momentId%40%22%3A%22%255B%255D%252FMoment%252Fid%22%7D%2C%22count%22%3A2%2C%22page%22%3A0%7D%2C%22count%22%3A2%2C%22page%22%3A0%7D%7D">点击这里测试</a></p>

<p>返回:</p>

<pre>
{
"[]":[
{
"User":{
"id":38710,
"sex":0,
"phone":"1300038710",
"name":"Name-38710",
"head":"http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000"
},
"Moment":{
"id":470,
"title":"Title-470",
"content":"This is a Content...-470",
"userId":38710,
"pictureList":["http://static.oschina.net/uploads/user/585/1170143_50.jpg?t=1390226446000"]
},
"Comment[]":[
{
"Comment":{
"id":4,
"parentId":0,
"momentId":470,
"userId":310,
"targetUserId":14604,
"content":"This is a Content...-4",
"targetUserName":"targetUserName-14604",
"userName":"userName-93781"
}
},
{
"Comment":{
"id":22,
"parentId":221,
"momentId":470,
"userId":332,
"targetUserId":5904,
"content":"This is a Content...-22",
"targetUserName":"targetUserName-5904",
"userName":"userName-11679"
}
}
]
},
{
"User":{
"id":70793,
"sex":0,
"phone":"1300070793",
"name":"Name-70793",
"head":"http://static.oschina.net/uploads/user/1174/2348263_50.png?t=1439773471000"
},
"Moment":{
"id":170,
"title":"Title-73",
"content":"This is a Content...-73",
"userId":70793,
"pictureList":["http://my.oschina.net/img/portrait.gif?t=1451961935000"]
},
"Comment[]":[
{
"Comment":{
"id":44,
"parentId":0,
"momentId":170,
"userId":7073,
"targetUserId":6378,
"content":"This is a Content...-44",
"targetUserName":"targetUserName-6378",
"userName":"userName-88645"
}
},
{
"Comment":{
"id":54,
"parentId":0,
"momentId":170,
"userId":3,
"targetUserId":62122,
"content":"This is a Content...-54",
"targetUserName":"targetUserName-62122",
"userName":"userName-82381"
}
}
]
}
]
}</code></pre>

<p> </p>

<h3><strong>客户端:</strong></h3>

<p>确实是一目了然,不用看文档了啊!</p>

<p>我被文档坑过很多次了都,文档多写或少写了一个字段,字段写错或多个空格,或者字段类型写错,都不知道浪费了多少调试和沟通时间!</p>

<p>有时候上头用app出了问题把我们叫过去,调试半天才发现原来是服务端改了接口!而且并没有及时通知我们!</p>

<p>有一次上头纠结要不要把单层评论改成QQ微信那种多级评论,自己按照以前的接口写了demo演示给上头看,上头很满意决定实现需求,结果后端都没和我商量自己改了接口返回的json结构,导致我这边不得不重构解析代码,真是醉了!</p>

<h3><strong>我:</strong></h3>

<p>用APIJSON就可以自己按需定制返回的JSON结构,没有接口,没有文档,就不会被文档坑了,也不会有你说的后端拍脑袋定JSON结构导致的客户端重构问题了哈哈!</p>

<h3><strong>客户端:</strong></h3>

<p>Nice!</p>

<h3><strong>服务端:</strong></h3>

<p>部分接口需要currentUserId和loginPassword的,你怎么搞?</p>

<h3><strong>我:</strong></h3>

<p>直接在最外层传,例如:</p>

<pre>
{
"currentUserId":100,
"loginPassword":1234,
"User":{
"id":1
}
}</code></pre>

<p> </p>

<h3><strong>服务端:</strong></h3>

<p>返回的状态码和提示信息放哪?</p>

<h3><strong>我:</strong></h3>

<p>也是在最外层,例如对以上请求的返回结果:</p>

<pre>
{
"status":200,
"message":"success",
"User":{
"id":"1",
"sex":"0",
"phone":"1234567890",
"name":"Tommy",
"head":"http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000"
}
}</code></pre>

<p> </p>

<h3><strong>客户端:</strong></h3>

<p>一次请求任意结构任意数据,方便灵活,不需要专门接口或多次请求?</p>

<p>以前我做了一个界面,上半部分是用户的信息,下半部分是他最近的动态,最多显示3个,类似于微信的详细资料。</p>

<p>我需要分别请求两次:</p>

<p>User:</p>

<pre>
<code >http://www.aaa.com/get/user?id=100</code></pre>

<p>Moment列表:</p>

<pre>
<code >http://www.aaa.com/get/moment/list?page=0&count=3&userId=100</code></pre>

<p>现在是不是可以这样:</p>

<p>User和Moment列表:</p>

<pre>
<code >http://www.aaa.com/get/{"User":{"id":100}, "[]":{"page":0, "count":3, "Moment":{"userId":100}}}</code></pre>

<p> </p>

<h3><strong>我:</strong></h3>

<p>对的,就是这样。</p>

<h3><strong>客户端:</strong></h3>

<p>好的。那重复数据怎么去除呢?</p>

<h3><strong>我:</strong></h3>

<p>比如QQ空间,里面有一个动态列表,每条动态里都有User和对应的动态内容Moment。</p>

<p>如果你进入一个人的空间,那就都是他的动态。</p>

<p>用传统的方式返回的列表数据里,每条动态里都包含同样的User,造成了数据重复:</p>

<p>请求:</p>

<pre>
<code >http://www.aaa.com/get/moment/list?page=0&count=5&userId=100</code></pre>

<p>返回:</p>

<pre>
{
"status":200,
"message":"success",
"data":[
{
"id":1,
"content":"xxx1",
...,
"User":{
"id":100,
"name":"Tommy",
...
}
},
{
"id":2,
"content":"xxx2",
...,
"User":{
"id":100,
"name":"Tommy",
...
}
},
...
]
}</code></pre>

<p>有5条重复的User。</p>

<p>而使用APIJSON可以这样省去4个重复User:</p>

<p>请求:</p>

<pre>
<code >http://www.aaa.com/get/{"User":{"id":100}, "[]":{"page":0, "count":5, "Moment":{"userId":100}}}</code></pre>

<p>返回:</p>

<pre>
{
"status":200,
"message":"success",
"User":{
"id":100,
"name":"Tommy",
...
},
"[]":[
{
"Moment":{
"id":1,
"content":"xxx1",
...
}
},
{
"Moment":{
"id":2,
"content":"xxx2",
...
}
},
...
]
}</code></pre>

<p> </p>

<p>如果之前已经获取到这个User了,还可以这样省去所有重复User:</p>

<p>请求:</p>

<pre>
<code >http://www.aaa.com/get/{"[]":{"page":0, "count":5, "Moment":{"userId":100}}}</code></pre>

<p>返回:</p>

<pre>
{
"status":200,
"message":"success",
"[]":[
{
"Moment":{
"id":1,
"content":"xxx1",
...
}
},
{
"Moment":{
"id":2,
"content":"xxx2",
...
}
},
...
]
}</code></pre>

<p> </p>

<p><strong>客户端:</strong></p>

<p>传统方式也可以服务端在接口增加一个返回格式字段,根据这个字段来决定是否去除重复User啊</p>

<h3><strong>我:</strong></h3>

<p>确实,不过这会导致以下问题:</p>

<p>1.服务端要新增字段和判断字段来返回不同数据的代码。</p>

<p>2.服务端要在文档里增加相关说明。</p>

<p>3.这个功能不一定用得上,因为客户端的UI需求往往很容易变化,导致缺少使用这个功能的条件,为了一两个版本去让服务端和客户端都折腾不值得。</p>

<p>而使用APIJSON就没这些问题,因为根本不需要接口或文档!而且是否去重只看客户端的意愿,服务端什么都不用做。</p>

<h3><strong>客户端:</strong></h3>

<p>这样啊,赞!</p>

<p>哦对了,APIJSON相比传统方式有没有缺少的功能啊?</p>

<h3><strong>我:</strong></h3>

<p>传统方式能做的APIJSON都能做。</p>

<p>客户端和服务端的http json交互:<br />
客户端 - 封装request -> 服务端 - 解析request - 生成response -> 客户端 - 解析response</p>

<p>传统方式request:</p>

<pre>
<code >base_url/lowercase_table_name?key0=value0&key1=value1...</code></pre>

<p>APIJSON request:</p>

<pre>
<code >base_url/{TableName:{key0:value0, key1:value1...}}</code></pre>

<p>TableName对应lowercase_table_name,key:value对应key=value,都是严格对应的,所以传统方式request里包含的信息APIJSON request一样可以包含,传统方式能实现的功能APIJSON肯定也都能实现。</p>

<h3><strong>客户端:</strong></h3>

<p>好的</p>

<h3><strong>服务端:</strong></h3>

<p>APIJSON怎么保证服务端返回给不同版本客户端的数据一致?</p>

<p>比如我上一个版本一个接口返回的值是a,现在这个版本要对所有版本客户端返回a+b,用传统方法只需要服务端把这个接口的返回值改下就好了,接口和客户端都不用改。</p>

<p>用APIJSON不就会导致对有些版本返回的是a,有些是a+b,这样就不能统一了?</p>

<h3><strong>我:</strong></h3>

<p>APIJSON对请求的解析和响应的操作都是在服务端完成的,对应的是APIJSON(Server)里的project。</p>

<p>服务端可以拦截到相关请求,比如请求a的值,把原本返回的a改成a+b就能保证对所有版本客户端返回a+b。也不需要客户端改代码,至于接口就更不用管了,因为根本没有接口。</p>

<h3><strong>服务端:</strong></h3>

<p>那我要不一致呢?给不同版本客户端返回不同的值。</p>

<h3><strong>我:</strong></h3>

<p>首先这种需求是极少的,比如降低电影票的价格,你不能让新版客户端里降价了,上个版本还是原价吧?</p>

<p>真有这种需求也可以通过客户端在请求里发送下版本号version,服务端根据版本号返回不同的值。</p>

<h3><strong>服务端:</strong></h3>

<p>也是啊。那用APIJSON怎么做权限处理?有些数据是要相关权限才能操作的。比如登录账号需要登录权限,付款需要支付权限。</p>

<h3><strong>我:</strong></h3>

<p>服务端获取到客户端的请求request后,在操作对应的table前用一个权限验证类去验证是否有操作权限,通过后才允许操作,否则返回错误信息。</p>

<p>权限验证类可以是这样的:</p>

<pre>
package zuo.biao.apijson.server.sql;

import java.rmi.AccessException;

import com.alibaba.fastjson.JSONObject;

import zuo.biao.apijson.StringUtil;

/**权限验证类

  • @author Lemon
    */
    public class AccessVerifyer {
    private static final String TAG = "AccessVerifyer: ";

    private static final int ACCESS_LOGIN = 1;
    private static final int ACCESS_PAY = 2;

    public static final String KEY_CURRENT_USER_ID = "currentUserId";
    public static final String KEY_LOGIN_PASSWORD = "loginPassword";
    public static final String KEY_PAY_PASSWORD = "payPassword";

    public static final String[] LOGIN_ACCESS_TABLE_NAMES = {"Work", "Comment"};
    public static final String[] PAY_ACCESS_TABLE_NAMES = {"Wallet"};

    /**验证权限是否通过

    • @param request
    • @param tableName
    • @return
      */
      public static boolean verify(JSONObject request, String tableName) throws AccessException {
      try {
      verify(request, getAccessId(tableName));
      } catch (AccessException e) {
      throw new AccessException(TAG + "verify tableName = " + tableName + ", error = " + e.getMessage());
      }
      return true;
      }
/**验证权限是否通过
 * @param request
 * @param accessId 可以直接在代码里写ACCESS_LOGIN等,或者建一个Access表。已实现登录密码的自动化处理,不需要写代码。
 * @return
 * @throws AccessException 
 */
public static boolean verify(JSONObject request, int accessId) throws AccessException {
    if (accessId < 0 || request == null) {
        return true;
    }
    long currentUserId = request.getLongValue(KEY_CURRENT_USER_ID);
    if (currentUserId <= 0) {
        throw new AccessException(TAG + "verify accessId = " + accessId
                + " >>  currentUserId <= 0, currentUserId = " + currentUserId);
    }
    String password;

    switch (accessId) {
    case ACCESS_LOGIN:
        password = StringUtil.getString(request.getString(KEY_LOGIN_PASSWORD));
        if (password.equals(StringUtil.getString(getLoginPassword(currentUserId))) == false) {
            throw new AccessException(TAG + "verify accessId = " + accessId
                    + " >> currentUserId or loginPassword error"
                    + "  currentUserId = " + currentUserId + ", loginPassword = " + password);
        }
    case ACCESS_PAY:
        password = StringUtil.getString(request.getString(KEY_PAY_PASSWORD));
        if (password.equals(StringUtil.getString(getPayPassword(currentUserId))) == false) {
            throw new AccessException(TAG + "verify accessId = " + accessId
                    + " >> currentUserId or payPassword error"
                    + "  currentUserId = " + currentUserId + ", payPassword = " + password);
        }
    default:
        return true;
    }
}

/**获取权限id
 * @param tableName
 * @return
 */
public static int getAccessId(String tableName) {
    if (StringUtil.isNotEmpty(tableName, true) == false) {
        return -1;
    }
    for (int i = 0; i < LOGIN_ACCESS_TABLE_NAMES.length; i++) {
        if (tableName.equals(LOGIN_ACCESS_TABLE_NAMES[i])) {
            return ACCESS_LOGIN;
        }
    }
    for (int i = 0; i < PAY_ACCESS_TABLE_NAMES.length; i++) {
        if (tableName.equals(PAY_ACCESS_TABLE_NAMES[i])) {
            return ACCESS_PAY;
        }
    }
    return -1;
}

/**获取登录密码
 * @param userId
 * @return
 */
public static String getLoginPassword(long userId) {
    // TODO 查询并返回对应userId的登录密码
    return "123456";//仅测试用
}

/**获取支付密码
 * @param userId
 * @return
 */
public static String getPayPassword(long currentUserId) {
    // TODO 查询并返回对应userId的支付密码
    return "123456";//仅测试用
}

}</code></pre>

<p> </p>

<h3><strong>服务端:</strong></h3>

<p>嗯,的确可行。刚看了项目主页的介绍,感觉APIJSON确实非常强大方便,连接口和文档都不用写了,也不会在健身或者陪女朋友看电影时突然接到客户端的电话了。</p>

<p>不过我还有一个问题,APIJSON是动态拼接SQL的,确实是灵活,但会不会导致SQL注入问题?</p>

<h3><strong>我:</strong></h3>

<p>APIJSON拼接SQL是在服务端完成的,客户端是不能直接发送SQL给服务端的。整个数据库操作都是服务端完全可控的,服务端可拦截危险注入,风险不比传统方式高。</p>

<h3><strong>服务端:</strong></h3>

<p>厉害了我的哥!我去下载试试哈哈!</p>

<h3><strong>客户端:</strong></h3>

<p>哈哈,我也要试试,请问怎么获取源码?免费的吗?</p>

<h3><strong>我:</strong></h3>

<p>已在Github和开源中国开源,完全免费。</p>

<p>Github: <a href="https://github.com/TommyLemon/APIJSON">https://github.com/TommyLemon/APIJSON</a></p>

<p>开源中国:<a href="http://git.oschina.net/Lemon19950301/APIJSON">http://git.oschina.net/Lemon19950301/APIJSON</a></p>

<h3><strong>服务端:</strong></h3>

<p>很棒!已Star!</p>

<h3><strong>客户端:</strong></h3>

<p>Star +1,顺便还Fork了一份研究嘿嘿!另外文档很详细赞一个!</p>

<h3><strong>我:</strong></h3>

<p>有什么问题或建议可以提issue或者发我邮件 <a href="mailto:tommylemon@qq.com">tommylemon@qq.com</a>,大家一起交流探讨哈!</p>

<h3><strong>服务端:</strong></h3>

<p>感觉我以后不用写一大堆接口了,不需要写兼容代码了,也不需要写文档了。可以专注于数据的处理、监控、统计、分析了哈哈!</p>

<h3><strong>客户端:</strong></h3>

<p>我也不用等服务端写好接口才能请求了,现在自己定制返回的JSON,看请求就知道返回的JSON结构,可以直接写解析代码了哈哈!</p>

<p> </p>

<p>(注:以上是对真实对话的改编。)</p><br />

<p> </p>

<p><strong>APIJSON,让接口和文档见鬼去吧!</strong></p>

<p><strong>

</strong></p>

<p><strong>下载试用(测试服务器地址:</strong>139.196.140.118:8080<strong>)</strong></p>

<p><a href="http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk">APIJSONClientApp.apk</a></p>

<p><strong>源码及文档(觉得不错就点Star支持下吧_)</strong></p>

<p><a href="https://github.com/TommyLemon/APIJSON">https://github.com/TommyLemon/APIJSON</a></p>

相关文章

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

    我: APIJSON,让接口和文档见鬼去吧! https://github.com/TommyLemon/AP...

  • iOS下 GraphQL与APIJSON的对比

    APIJSON的口号是: 后端接口和文档自动化,前端(客户端) 定制返回JSON的数据和结构! APIJSON的简...

  • 希望被看见的生命力

    让完美的想法见鬼去吧

  • 让前任见鬼去吧!

    01 去年年底,朋友圈一夜之间驻守了大波《前任三》观影大军,一个个看完电影后犹如打了鸡血一般,纷纷晒出两张电影票并...

  • 让加班见鬼去吧

    快到年终了,各种考核验收一股脑全涌过来,所有事情堆到一块,足够让你手忙脚乱。往往是,正在做这个表格还没做好,领导又...

  • 让誓言见鬼去吧

    生活不止眼前的苟且,还有诗和远方的田野…… 许巍微哑的嗓音吟出这句歌词的时候,我的脑海里浮现的却是高晓松略显粗犷的...

  • 让烦恼见鬼去吧

    你的烦恼一半是对自己的不满一半是对别人的不满,可是你没看到整日里天灾水祸,车毁人亡…那么多生命还没搞清状况就匆...

  • 让压力见鬼去吧

    今天公布中考成绩。上午九点钟,这爷俩围在电脑前,不知道什么原因,教育局的网站一直无法登陆,也可能同一时间登陆的人...

  • 让运气见鬼去吧

    也估计只有我这种傻瓜才会有“自己人品不错,运气通常都会很好”这种想法。我也不知道哪来的信心,总觉得自己聪明过人,智...

  • 让焦虑见鬼去吧!

    一、 不知为啥,今天整个人突然陷入莫明的焦虑和沮丧中,感觉干什么都没劲,看什么都不顺眼,对自己更是十二分的不满,所...

网友评论

  • longzekai:这排版还可以再乱一点么?:smile:
    孤独的探索号:@longzekai 前段时间简书抽风了,我正好修改了几篇文章,一保存就乱码,自己尝试过,也和客服沟通过,怎么都还原不了,除非重新写一遍。建议看这篇内容更新过的:
    https://my.oschina.net/tommylemon/blog/805459
  • 孤独的探索号:APIJSON JavaScript版已发布,使用超级简单,欢迎使用,欢迎反馈,记得Star哦
    https://github.com/TommyLemon/APIJSON-JS
  • 孤独的探索号:APIJSON服务端已升级,
    Parser#getArray返回结果中
    Item[]:{0:{Table:{}}, 1:{Table:{}}...}
    已改为
    Item[]:[{Table:{}}, {Table:{}}...],
    解析更方便。

    在客户端JSONResponse#format会转化为
    itemList:[{Table:{}}, {Table:{}}],
    如果 Item.equals(Table),则将 {Table:{Content}} 转化为 {Content}
  • 孤独的探索号:感谢 @香脆的大鸡排 的建议,昨天一个灵感,今天就完成了JSON->Java自动化工具,嘿嘿
    http://files.cnblogs.com/files/tommylemon/APIJSON(ADT).apk
    从最下方【自动生成代码】 进去
  • 孤独的探索号:APIJSON版本大更新:
    1.新增模糊搜索;
    2.新增远程调用函数;
    3.新增匹配范围;
    4.新增支持JDK8;
    5.其它功能完善;
    6.解决一些bug。

    最重要的是,一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
  • FlySheep_ly:你的做法是客户端直接拿到的是服务端数据库里的原始数据吗?
    孤独的探索号:@FlySheep_ly 对的,每个产品都是为了解决某个或某些问题而生的,一般来说小公司只能开发小型系统,只有大公司才能开发大型系统。APIJSON解决的问题在小公司很容易出现并且容易造成致命的影响(开发周期长、产品上线迟导致资金链断裂而倒闭),但大公司因为资源(人才、资金、管理)充裕可以很好地避免这些问题。APIJSON降低了开发门槛和成本,使得小公司也能快速实现产品、节约资源,提高自己的竞争力。
    FlySheep_ly:@TommyLemon 这样对于小型系统问题不大,对于大型系统就不太适合了
    孤独的探索号: @FlySheep_ly 服务端数据库原始数据转为JSON字符串返回给客户端
  • 猎人1987:有用
    孤独的探索号:APIJSON版本大更新。一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
    孤独的探索号:@猎人1987 :grin:
  • 孤独的探索号:我搭了个阿里云CES服务器,大家可以不用搭服务器,直接修改客户端App的Query界面下编辑框里的默认IP地址为 139.196.140.118:8080 测试哈!
    http://files.cnblogs.com/files/tommylemon/APIJSON(ADT).apk
  • 喵媛:Mark一下,后面慢慢学习……
    孤独的探索号:APIJSON版本大更新。一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
    孤独的探索号:@喵媛 欢迎交流探讨 :smile:
  • SaiWu:不明觉厉
    孤独的探索号:@SaiWu 可以看下文档哦
    https://github.com/TommyLemon/APIJSON
  • 帝Bug:看上去思路不错,就是不知道坑多不多
    孤独的探索号:APIJSON版本大更新。一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
    孤独的探索号:@周Jay 放心,我与你同在 :smile:
  • mmaqshen:先收了,下午详读,谢谢分享
    孤独的探索号:APIJSON版本大更新。一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
    孤独的探索号:@mmaqshen 有什么问题或建议可以一起交流探讨哈 :blush:
  • 无神:一种全新的数据传输形式,引领时代潮流!很棒!
    无神:@TommyLemon 我用的iPhone!没有Android机!
    孤独的探索号:APIJSON版本大更新。一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
    孤独的探索号:@无神 感觉自己要骄傲了嘿嘿 :stuck_out_tongue_winking_eye:
  • 6494df96c4e2:赞
    孤独的探索号:APIJSON版本大更新。一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
    孤独的探索号:@TuringHero 谢谢 :smile:
  • 匡风含情:請求的大小多到爆.
    孤独的探索号:@TommyLemon 而且APIJSON的客户端工程提供了JSONRequest类,可以很方便地封装请求,还不需要像传统方式那样addParameter后再拼接键值对,请求的代码量反而更少。
    孤独的探索号:@倪神州 仅从请求上看,确实比传统方式数据多;但从整体上看,APIJSON让客户端看请求知结果,所求即所得,让服务端和客户端都大幅降低了开发和沟通成本,所以是值得的 :smile:
  • e9a44a336dfe:你很乐观
  • e9a44a336dfe:你很乐观
  • 段潇涵:GraphQL 小火,就出现了这么多类似的东西吗?无论谁先做出来的,赶在这个时机来说总感觉有跟风的嫌疑,并且这个东西是需要服务端做你所谓的 APIJSON 查询结构的解析器的,哪有你说的那么简单
    孤独的探索号:@段潇涵 OK,欢迎交流探讨 :smile:
    段潇涵:@TommyLemon 我不是莫名其妙将你定义为跟风,我原话说的很明白,是因为放在这个时机显得跟风,我会仔细研读一下你的代码再回来辩论。
    孤独的探索号:@段潇涵
    你看下APIJSON(Sever)里的服务端工程,RequestParser就是解析器,不用自己做。
    我发布APIJSON前是不知道有GraphQL的,莫名其妙被你定义为跟风。APIJSON和FaceBook的GraphQL确实比较像,尤其是理念一样,都是客户端定制服务端返回的JSON。但它的请求语法复杂,学习成本高,全新的格式需要从客户端到服务端全都支持,代码量很大(graphql-java有100多个java类,几乎都用于对新格式的封装和解析),迁移风险也很大。APIJSON的请求用的是JSON这种通用的格式,没有额外的语法,容易上手,展示更直观,解析更方便,代码量小(仅10多个java类),完美兼容传统HTTP接口,几乎无迁移风险(可以逐步迁移,先把未实现的功能用APIJSON去做,以前的接口也不用改)。
  • dongjunkun:赞,有机会试一下,确实能够省下不少沟通的时间
    孤独的探索号:APIJSON版本大更新。一个面向普通用户的APP初步开发完成,基于APIJSON+ZBLibrary打造,注册登录、查看搜索、上传更新等五脏俱全。欢迎使用,欢迎反馈

    http://files.cnblogs.com/files/tommylemon/APIJSONApp.apk
    孤独的探索号:@dongjunkun 谢谢 :smile:

本文标题:APIJSON, 让接口和文档见鬼去吧!

本文链接:https://www.haomeiwen.com/subject/ohjumttx.html