APP后端设计分享

乐乎APP接口设计规范v1

张遂程 2018年02月06日16:15:03

前言

没有最优的方案,只有最适合的方案,本文指出对APP接口设计的一些规范与大家分享和共勉,涉及到APP接口设计规范v1.0,设计案例的分享,和一些PHP编码的要求,目的在于开发出性能优异,结构清晰,维护便捷,安全,和高拓展性的接口。如果有说得不正确的地方,也请大家指出。

经验学习

在项目中,要做到融会贯通,首先就应该做到多学习,学习大厂的经验和总结,如果能避免到别家遇到的坑,那么就最好了,如果避免不到,那么也能做到心中运筹帷幄。程序开发中有句很流行话就是,"不要重复造轮子",要"时刻明确自己是搬砖民工,不是烧砖的窑"。

新浪微博 open api

获取用户详情接口设计 http://open.weibo.com/wiki/2/friendships/friends
{
    "users": [
        {
            "id": 1404376560,
            "screen_name": "zaku",
            "name": "zaku",
            "province": "11",
            "city": "5",
            "location": "北京 朝阳区",
            "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。",
            "url": "http://blog.sina.com.cn/zaku",
            "profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1",
            "domain": "zaku",
            "gender": "m",
            "followers_count": 1204,
            "friends_count": 447,
            "statuses_count": 2908,
            "favourites_count": 0,
            "created_at": "Fri Aug 28 00:00:00 +0800 2009",
            "following": false,
            "allow_all_act_msg": false,
            "remark": "",
            "geo_enabled": true,
            "verified": false,
            "status": {
                "created_at": "Tue May 24 18:04:53 +0800 2011",
                "id": 11142488790,
                "text": "我的相机到了。",
                "source": "新浪微博",
                "favorited": false,
                "truncated": false,
                "in_reply_to_status_id": "",
                "in_reply_to_user_id": "",
                "in_reply_to_screen_name": "",
                "geo": null,
                "mid": "5610221544300749636",
                "annotations": [],
                "reposts_count": 5,
                "comments_count": 8
            },
            "allow_all_comment": true,
            "avatar_large": "http://tp1.sinaimg.cn/1404376560/180/0/1",
            "verified_reason": "",
            "follow_me": false,
            "online_status": 0,
            "bi_followers_count": 215
        },
        ...
    ],
    "next_cursor": 5,
    "previous_cursor": 0,
    "total_number": 668
}

  • 面向对象设计:用户是一个完整的对象,其中每个用户包含一个最新微博的对象,微博对象也是一个相对完整的对象,按照新浪微博的APP接口设计,获取每一个用户列表,都能获取到列表用户的最新微博信息。
  • 错误信息的返回:主接口中没有直接对错误信息的定义,但凡是能够获取到信息,都认为是正确,而错误信息的定义则是用另一种数据格式来表示。
{
    "request" : "/statuses/home_timeline.json",
    "error_code" : "20502",
    "error" : "Need you follow uid."
}
  • 错误信息的说明:'request'表示当前请求的接口;'error_code'表示错误编号;'error'表示错误的提示文字

淘宝开放平台

查询买家信息 http://open.taobao.com/docs/api.htm?spm=a219a.7629065.0.0.5Zpljz&apiId=21348
  • 正常响应
{
    "user_buyer_get_response":{
        "user":{
            "nick":"hz0799",
            "sex":"m",
            "avatar":"http://assets.taobaocdn.com/app/sns/img/default/avatar-120.png",
            "open_uid":"324324324"
        }
    }
}
  • 异常响应
{
    "error_response":{
        "sub_msg":"非法参数",
        "code":50,
        "sub_code":"isv.invalid-parameter",
        "msg":"Remote service error"
    }
}
  • 错误响应也是通过错误code来识别的,每个code对应一个错误内容

其他开放API

除了上文说的响应方式外,还有一种API响应方式也是比较流行,代表者是百度,高德,支付宝等。

  • 百度举例
{  
    address: "CN|北京|北京|None|CHINANET|1|None",    #详细地址信息  
    content:    #结构信息  
    {  
        address: "北京市",    #简要地址信息  
        address_detail:    #结构化地址信息  
        {  
            city: "北京市",    #城市  
            city_code: 131,    #百度城市代码  
            district: "",    #区县  
            province: "北京市",    #省份  
            street: "",    #街道  
            street_number: ""    #门牌号  
        },  
        point:    #当前城市中心点  
        {  
            x: "116.39564504",    #当前城市中心点经度
            y: "39.92998578"    #当前城市中心点纬度
        }  
    },  
    status: 0    #结果状态返回码  
}
  • 支付宝举例
{
    "alipay_trade_precreate_response": {
        "code": "10000",
        "msg": "Success",
        "out_trade_no": "6823789339978248",
        "qr_code": "https://qr.alipay.com/bavh4wjlxf12tper3a"
    },
    "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"
}
  • 这类API相对新兴设计,在API响应上,不区分正确响应和错误响应的结构,采用统一返回方式,其中返回的code 来区分正确还是错误,其中的message来分别给出正确和错误的响应消息。

小结

  • API设计中,要根据自己的业务类型和面向群体来综合考虑
  • 都对错误级别进行了划分,并用不同的错误code来表示
  • API面向对象设计并不是面向页面设计,这样的API就具有了多端不同展示的能力
  • 响应主体设计中,个人比较倾向统一的返回,也就是现在我们正在使用的三段式返回,不同的客户端不用去写过多的兼容代码和错误处理,错误处理全部由服务端来完成。
  • 错误处理,目前我们的错误处理机制都还比较简单,就APP而言,只有 '0' '1' '1001',三种识别码和对应的中文提示内容。如果我们后续要支持多种语言的提示,就必须使用error_code,然后由客户端自行提示。

接口设计规范

与前端交互部分

这里概念的定义为与APP部分相互的部分,我们将从安全,版本兼容,命名规范,迭代,面向对象等多个方面说起

接口安全部分

在app的后台设计中,一个很重要的因素是考虑通讯的安全性。

避免信息的泄露,最简单的方案是所有涉及到安全性的api请求,都必须要使用https协议。

因此,我们需要考虑的要点有:

  1. 在app和后台,都不能保存任何用户密码的明文
  2. 在app和后台通讯的过程中,怎么保证用户信息的安全性
  3. 在app中,根据安全考虑,用户的操作分为两类:
    1. 用户登录
    1. 注册操作
      用户的其他操作
  1. 在第一点,用户登录注册操作中,是会出现用户密码,所以在这个过程中,必须要使用https通讯,保证通讯的安全。
  2. 在第二点,用户的其他操作,怎么保证这部分通讯的安全呢?
    在我们的设计中,是采用了公钥加私钥保证安全。用户的id是公钥,通过一定的算法对用户的id进行加密得到一个加密字符串是私钥。当用户登录或注册后,通过https把公钥加私钥返回给app客户端。
  3. 但这个方法有个缺点,当别人截获了这个url时可以重复使用,所以有个改进方法是在传递的参数中增加时间戳,当发现这个时间戳离现在的时间已经很久了,就判断这个url已经失效了。但用时间戳怎么保证app的时间和服务器的时间同步?==可以在app每次启动和注册登录时和服务器同步时间,然后在app内建一个时钟,时间戳在这个app的内部时钟获取,防止用户修改了手机的时间。==
  4. 当然,这些操作做完了,也不能保证100%的安全,只能为攻击增加成本。

效率

APP对服务器端要求是比较严格的,在移动端有限的带宽条件下或者弱网络下,要求接口响应速度要快,,抛开后端的开发框架效率来说,对数据要求也比较严格,如果能做到app需要什么数据就传什么数据,不可多传,过多的数据量影响处理速度,最重要的是影响传输效率那么自然效率是最高的,但是这之间也要有个取舍,效率和接口设计思想之间,后面我们会提到面向对象的设计思想。

面向对象的设计思想

Restful风格:RESTfu设计原则,它被RoyFelding提出(在他的"基于网络的软件架构"论文中第五章)。而REST的核心原则是将你的API拆分为逻辑上的资源。这些资源通过http被操作(GET,POST,PUT,DELETE)。但现在看,一般的操作只有两种:GET ,POST。

  • 这个设计原则最简单的应用就是面向对象设计而不是页面来设计api。最开始的时候,app的一个页面需要什么数据,api就返回什么数据。结果随着app的UI不断改版,需要的数据不断变化,不停地修改api,最后当api的改动会影响以前的版本的时候,只能写一个新的api版本,最后弄得api中有很多version/2,version/3这样的标志,恶梦!

  • ==但根据object来设计,又有一个问题,一个大object可能包含很多小object,是一个api返回全部小object,还是分为多个api返回?根据业务和技术,带宽等仔细考虑吧。==

  • 目前我们的接口设计是根据业务来定制接口和返回,假设页面上只显示五个字段,那么后端就需要针对这个页面进行设计。

  • 当然这这样的好处是显而易见的,在和客户端交互的过程中,传输的数据全是有用的数据,极大地节约了网络资源,而且只需请求一个接口,接口就返回了所有界面显示的数据,在弱网状态下,加快响应速度。

  • 新浪微博的做法:打开个人中心,会分多次进行请求,'users/counts'批量获取用户的粉丝数、关注数、微博数,'users/domain_show'个性域名相关,'users/show'获取主要信息,这是比较极端的做法,仅供参考。

  • 下面是一个简单的例子


    APP后端设计分享_第1张图片
    image

    返回的数据结构如下

{
    "brand_name": "奥迪",
    "car_model": "SUV",
    "emission_standard": "国五",
    "car_owner": {
        "name ": "张三 ",
        "driving_years": "5年",
        "id": "123 ",
    }
}

其中车主是一个对象,车子是一个对象,两者是既有关系又相对独立。
我的建议是,新设计的接口,需要考虑到多端不同展示,尽可能的偏向于面向对象,少量特殊处理可以面向页面。当然,后端代码上,都是以对象的形式存在,逻辑必须清楚。

API命名规则

其中一个原则,一看api名字就知道这个api是干啥。但是有个问题就是当你要负责几十甚至上百个api,你就知道不能"望名知api"是个什么样的痛苦。
就拿一个接口来举例吧

/User/userRedDot/version/1

后端代码部分

你可能感兴趣的:(APP后端设计分享)