HTTP接口设计及日志打印

任何一个稍大的项目中,web接口的使用是少不了的,不管C2S还是S2S都会依赖于http的接口。下面对这一两年来写过各种Http接口做一个总结。

大致可以分为以下五点:

1、使用requestId来记录追踪请求

2、只在body中接收json字符串的请求,避免产生编码问题

3、返回适当的数据结构

4、打印有用的日志

5、提供可阅读的文档

第一点,使用requestId来记录追踪请求。如果你这么做了,当你查找定位问题的时候就会知道这是一个多么有用的规则。这里可以强制请求中用UUID作为requestId,服务器返回时带上同样的UUID。或者业务上没有此需求,则可以通过对每个请求生成一个唯一的id来标识,这个方法在第四点,日志中会介绍。

第二点,除了请求的数据非常简单或者特殊情形一定需要使用GET方法以外,所有的请求都应尽量使用POST方法,并且规定请求参数为JSON字符串,放在RequstBody中,尽量不要将额外的参数信息放在form-encoded里面,这样不仅可以有效避免编码问题,同时也可以与接口返回的JSON BODY对应。

第三点,设计每个API的时候,要定义好返回状态码,错误信息,以及有效信息。大部分情况下,HTTP API应使用JSON作为ResponseBody,这要可以与请求相对应,同时可以方便接口的扩展。下面是我常用的返回数据结构:public class ResponseEntry {

private int code; // 状态码

    private String result; // 描述信息

    private Object data; // 有效信息

    public ResponseEntry(int code) {
        this.code = code;
    }

    public ResponseEntry(int code, String result) {
        this.code = code;
        this.result = result;
    }

   // 省略Getter and Setter
    @Override
    public String toString() {
        return "ResponseEntry{" + "code=" + code + ", result=‘" + result + ‘\‘‘
            + ", data=" + data + ‘}‘;
    }

    public String toJSONString() {
        return JSON.toJSONString(this);
    }
}

code的存在可以让请求的客户端更准确的确定返回的信息,判断此次请求的结果。ResponseCode的设计也应遵循一定的规则,如200通常表示成功,404通常表示not found等。如果你使用springmvc作为框架开发,那么我们可以在接口中直接返回ResponseEntry对象,并通过配置servlet-context使其自动转为json字符串并返回。如下所示:

@ResponseBody
    @RequestMapping(value = "/communicate", method = RequestMethod.POST)
    private ResponseEntry communicate(@RequestBody String jsonBody) {
    /* code */
}
<mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <!-- fastjosn spring support -->
            <bean id="jsonConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <!--<value>application/json;charset=UTF-8</value>-->
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

这里用的是fastjson作为转换,也可以使用默认的jackson或其他json处理方法。

第四点,打印有用的日志。在接口中打印出必要的信息,可以有效的帮助查找定位问题。通常需要打印出Request和Response的内容。并用requestId来表示每个Response和对应的Request。在Http接口设计中,我们可以加入一个Filter用来打印log,这样就不必再每一个API都去做一遍打印输入输出的动作。可以使代码更加简洁。这里代码比较多,就不贴了,参看源码github

第五点,当完成接口,并测试通过以后,应该给出一份可阅读的接口文档,这不仅仅是帮助其他人使用你的API,同时在写文档的过程中,可以review一遍自己的代码,保证没有逻辑上的错误等等。

时间: 2024-08-28 19:53:11

HTTP接口设计及日志打印的相关文章

架构设计 - 日志管理接口设计

在后端代码中,日志无处不在,自己设计自己的一套日志管理代码,提供一套好用的日志接口将大大方便代码的开发. 其中在日志管理代码的编写中,主要有以下难点: 1.数目不确定的入参函数编写 2.日志权限控制 3.日志输出形式. 接口设计: 1.提供三类日志打印形式:1)控制台打印信息,类似printf的接口封装 2)函数追踪接口,打印当前代码的文件名,函数名及行,以及一些设定的输出参数 3)日志打印函数,提供打印级别控制,且打印内容输出到日志文件中 2.提供日志级别控制:1)在打印日志时提供当前日志级别

Python+request 分模块存放接口,多接口共用参数URL、headers的抽离,添加日志打印等《三》

主要介绍内容如下: 1.分模块存放接口 2.多接口共用参数URL.headers的抽离为配置文件 3.添加日志打印 4.一个py文件运行所有所测的接口 如上介绍内容的作用: 1.分模块存放接口:方便多人协作,对模块接口的分开存放,方便后期新增模块接口的录入,也方便接口出现报错后,定位模块 2.多接口共用参数URL.headers的抽离为配置文件: (1)URL:单独进行配置文件中的修改,主要是方便后期接口域名出现变化,方便更改,示例,本次URL前缀为:https://127.0.0.1,下次开发

php后台对接ios,安卓,API接口设计和实践完全攻略,涨薪必备技能

2016年12月29日13:45:27 关于接口设计要说的东西很多,可能写一个系列都可以,vsd图都得画很多张,但是由于个人时间和精力有限,所有有些东西后面再补充 说道接口设计第一反应就是restful api 请明白一点,这个只是设计指导思想,也就是设计风格 ,比如你需要遵循这些原则 原则条件REST 指的是一组架构约束条件和原则.满足这些约束条件和原则的应用程序或设计就是 RESTful.Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的.从客户端到服务

syslog日志打印

最近syslog出了一次问题,我们配置了不同appname打印到不同文件.现在用不同appname打印log的时候,偶然会混在一起.检查过配置后,觉得不是配置问题,如果是配置问题应该每一条都会打错位置.后来同事发现是c接口线程不安全导致的.这里不是指syslog的libc接口线程不安全,是我们调用syslog的lua接口封装有问题. syslog是一个历史悠久的日志记录标准.一般的日志记录流程是这样的:内核会在内核空间,创建好一个ring buffer,然后调用printk函数在这个buffer

系统间接口设计

最近两年一直在和银行.公安.保险.民政等第三方单位之间做接口,写的接口文档不下30份,最初的接口文档漏洞百出,改了又改,丢了不少人,也被批评.埋怨,指责了很多次,久而久之,明白了一个最重要的道理,协作决定接口.双方谈接口时,技术不是最重要的,要兼顾双方技术,成本,工期等等很多因素.但仍有很多技术层面的心得,恰巧上周参与温昱老师的一个性能设计的外训,里面老师讲到了接口设计,正好回来一起整理一下接口设计的经验.主要从3个方面总结一下系统间接口设计:接口定义.接口实现.其他一些注意事项. 一.接口定义

PHP/TP5 接口设计中异常处理

PHP提供 Exception 类来处理异常 new Exception('错误信息(默认为空)','错误代码(默认0)','异常链中前一个异常') 然后可以通过 e -> getMessage() 获取异常信息 e -> getCode() 获取异常错误码 处理异常 try { //可能抛出异常代码 throw new Exception("Error Processing Request", 1); } catch (Exception $e) { // 1. 记录日志

C++ 11可变参数接口设计在模板编程中应用的一点点总结

概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量(或属性,C#中属性和成员变量还是有区别的): 类的成员方法: 从编译器的角度看,我们必须明确指定以上3部分,才算完整地定义了一个类并且编译通过. 所谓的“类弱化”,是指类的设计者在定义类的时候,并没有完整定义一个类,而是把类的其中一部分的定义留给类的使用者. 从传统才c++98看,通过模板类,使用

Atitit.自定义存储引擎的接口设计&#160;api&#160;标准化&#160;attilax&#160;总结&#160;&#160;mysql

Atitit.自定义存储引擎的接口设计 api 标准化 attilax 总结  mysql 1. 图16.1:MySQL体系结构1 2. 16.7. 创建表create()虚拟函数:2 3. 16.8. 打开表 open()2 4. ---------------------------------------------------------------------------------------------------------------------2 5. 16.9. 实施基本的

电子商务系统的设计与实现(五):账务系统的功能接口设计

电商系统.p2p网贷系统.第三方支付都可以有自己的账务系统,账务系统与用户系统可以完全独立,不需要用户ID等信息,只提供给其它系统若干接口.服务可以用WebService的方式实现,对内提供服务非常方便,调用接口,就要调用普通的API一样.也可以做成HTTP的方式,外部使用相对麻烦一些.疑问:WebService提供的接口,可以直接用HTTP的方式调用么? 账务系统的功能接口设计 1.开户  可选输入:用户ID.账户资金类型(人民币.美元)  功能描述:创建一个账户.  理论上不需要存入用户的I