java作为一门后端语言,其厉害之处在于web,大家比较熟知的各种网络应用,java都能做,那么在这个移动优先的时代,如何继续发挥java的强大呢。通常是让java作为一个app的服务端,为app客户端提供数据,做业务逻辑,所以我们用java来写接口,app客户端访问接口返回json文件进行解析,最后实现业务逻辑。这种方式就是我们通常所说的restful架构风格的api。

  restful是一种架构思想,最初由Roy T. Fielding(HTTP/1.1协议专家组负责人)在其2000年的博士学位论文中提出。HTTP就是该架构风格的一个典型应用,其核心思想就是前后端分离,前端通过http请求,如www.xxxx.com/demo/username/password  来访问后端的接口,然后后端将处理好的数据封装为json返回,这样,后端只需关注具体逻辑 提供接口,而前端只关心界面,提高了程序解耦性。

  在移动优先的时代,restful极为重要。通常一套后台可以让多种终端访问,包括移动端,pc端。

  在java中比较容易实现restful的是SpringMVC框架,他提供了一套处理json的注解。通过@ResponseBody返回json数据,通过@ResquestBody解析json。

  

REST(Representational State Transfer)表象化状态转变(表述性状态转变),在2000年被提出,基于HTTP、URI、XML、JSON等标准和协议,支持轻量级、跨平台、跨语言的架构设计。是Web服务的一种新的架构风格(一种思想)

什么是轻量级:

代码不被侵入(正例:SpringMVC中不用接口和继承,仅用注解完成。反例:Struts中每一个Action都要继承核心控制器),轻量级跟包大小无关。耦合性越低,越轻量。

REST架构的主要原则

  • 网络上每一个资源都有一个资源标志符,可以用来唯一地标识该资源

  • 对资源的操作不会改变标识符。

  • 同一资源有多种表现形式(xml、json)

  • 所有操作都是无状态的(Stateless)

符合上述REST原则的架构方式称为 RESTful

RESTful资源操作

http方法 资源操作 幂等 安全
GET SELECT 
POST  INSERT 
PUT  UPDATE 
DELETE  DELETE 

幂等性:对同一REST接口的多次访问,得到的资源状态是相同的。

安全性:对该REST接口访问,不会使服务器端资源的状态发生改变。

注意,默认情况下,PUT请求是无法提交表单数据的,在Spring MVC项目中需要在web.xml中添加过滤器解决:

  1. <!-- 解决PUT请求无法提交表单数据的问题 -->
  2. <filter>
  3. <filter-name>HttpMethodFilter</filter-name>
  4. <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>HttpMethodFilter</filter-name>
  8. <url-pattern>/*</url-pattern>
  9. </filter-mapping>

URL设计

  • 动词的覆盖

有些客户端只能使用GETPOST两种方法。服务器必须接受POST模拟其他三个方法(PUTPATCHDELETE)。这时,客户端发出的 HTTP 请求,要加上X-HTTP-Method-Override属性,告诉服务器应使用哪一个动词,覆盖POST方法。

  1. POST /api/Person/4 HTTP/1.1
  2. X-HTTP-Method-Override: PUT
  3. //上面代码中,X-HTTP-Method-Override指定本次请求的方法是PUT,而不是POST。
  • 宾语必须是名词

宾语就是 API 的 URL,是 HTTP 动词作用的对象。它应该是名词,不能是动词。比如,/articles这个 URL 就是正确的,而下面的 URL 不是名词,所以都是错误的。

  1. /getAllCars
  2. /createNewCar
  3. /deleteAllRedCars
  • 复数 URL

既然 URL 是名词,那么应该使用复数,还是单数,没有统一的规定,但是常见的操作是读取一个集合,比如GET /articles(读取所有文章),这里明显应该是复数。

为了统一起见,建议都使用复数 URL,比如GET /articles/2要好于GET /article/2

  • 避免多级 URL

常见的情况是,资源需要多级分类,因此很容易写出多级的 URL

  1. //比如获取某个作者的某一类文章。这种 URL 不利于扩展,语义也不明确,往往要想一会,才能明白含义。
  2. GET /authors/12/categories/
  3. //更好的做法是,除了第一级,其他级别都用查询字符串表达。
  4. GET /authors/12?categories=2
  5.  
  6. //下面是另一个例子,查询已发布的文章。你可能会设计成下面的 URL。
  7. GET /articles/published
  8. //查询字符串的写法明显更好。
  9. GET /articles?published=true

接口示例

  1. //传统URL请求格式:
  2. http://127.0.0.1/user/query/1 GET 根据用户id查询用户数据
  3. http://127.0.0.1/user/save POST 新增用户
  4. http://127.0.0.1/user/update POST 修改用户信息
  5. http://127.0.0.1/user/delete GET/POST 删除用户信息
  6.  
  7. //RESTful请求格式:
  8. http://127.0.0.1/user/1 GET 根据用户id查询用户数据
  9. http://127.0.0.1/user POST 新增用户
  10. http://127.0.0.1/user PUT 修改用户信息
  11. http://127.0.0.1/user DELETE 删除用户信息

服务器回应

  • 不要返回纯本文

API 返回的数据格式,不应该是纯文本,应该是一个 JSON 对象,这样才能返回标准的结构化数据。所以,服务器回应的 HTTP 头的Content-Type属性要设为application/json

客户端请求时,也要明确告诉服务器,可以接受 JSON 格式,即请求的 HTTP 头的ACCEPT属性也要设成application/json。如:

  1. GET /orders/2 HTTP/1.1
  2. Accept: application/json
  • 发生错误时,不要返回 200 状态码
  1. //有一种不恰当的做法是,即使发生错误,也返回200状态码,把错误信息放在数据体里面,就像下面这样,解析数据体以后,才能得知操作失败。这张做法实际上取消了状态码,这是完全不可取的。
  2. HTTP/1.1 200 OK
  3. Content-Type: application/json
  4.  
  5. {
  6. "status": "failure",
  7. "data": {
  8. "error": "Expected at least two items in list."
  9. }
  10. }
  11.  
  12. //正确的做法是,状态码反映发生的错误,具体的错误信息放在数据体里面返回。
  13. HTTP/1.1 400 Bad Request
  14. Content-Type: application/json
  15.  
  16. {
  17. "error": "Invalid payoad.",
  18. "detail": {
  19. "surname": "This field is required."
  20. }
  21. }
  • 提供链接

API 的使用者未必知道,URL 是怎么设计的。一个解决方法是,在回应中,给出相关链接,便于下一步操作。这样的话,用户只要记住一个 URL,就可以发现其他的 URL,这种方法叫做 HATEOAS。

  1. //举例来说,GitHub 的 API 都在 api.github.com 这个域名。访问它,就可以得到其他 URL。
  2. {
  3. ...
  4. "feeds_url": "https://api.github.com/feeds",
  5. "followers_url": "https://api.github.com/user/followers",
  6. "following_url": "https://api.github.com/user/following{/target}",
  7. "gists_url": "https://api.github.com/gists{/gist_id}",
  8. "hub_url": "https://api.github.com/hub",
  9. ...
  10. }

  11. //上面的回应中,挑一个 URL 访问,又可以得到别的 URL。对于用户来说,不需要记住 URL 设计,只要从 api.github.com 一步步查找就可以了。
  12. //HATEOAS 的格式没有统一规定,上面例子中,GitHub 将它们与其他属性放在一起。更好的做法应该是,将相关链接与其他属性分开。
  13. HTTP/1.1 200 OK
  14. Content-Type: application/json
  15.  
  16. {
  17. "status": "In progress",
  18. "links": {[
  19. { "rel":"cancel", "method": "delete", "href":"/api/status/12345" } ,
  20. { "rel":"edit", "method": "put", "href":"/api/status/12345" }
  21. ]}
  22. }

REST以及RESTful的更多相关文章

  1. Restful资源文章

    理解RESTful架构 RESTful API设计指南 RESTful架构详解 NodeJs的RESTful API

  2. 【接口开发】浅谈 SOAP Webserver 与 Restful Webserver 区别

    接口,强大,简单,交互,跨越平台 下面简单阐述这两大接口思想 一 REST: REST是一种架构风格,其核心是面向资源,REST专门针对网络应用设计和开发方式,以降低开发的复杂性,提高系统的可伸缩性. ...

  3. (转载) RESTful API 设计指南

    作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...

  4. angular中使用ngResource模块构建RESTful架构

    ngResource模块是angular专门为RESTful架构而设计的一个模块,它提供了'$resource'模块,$resource模块是基于$http的一个封装.下面来看看它的详细用法 1.引入 ...

  5. Linux学习日记-WCF RestFul的部署(三)

    一.关于WCF 的部署 默认的wshttp风格的wcf是很容易部署上去的,但是这里给个建议尽量不要使用WCF的配置文件去部署尽管 我们都已经很熟悉了,在使用配置文件你会发现各种蛋疼的问题. 二.WCF ...

  6. Node.js实现RESTful api,express or koa?

    文章导读: 一.what's RESTful API 二.Express RESTful API 三.KOA RESTful API 四.express还是koa? 五.参考资料 一.what's R ...

  7. Restful WebApi项目开发实践

    前言 踩过了一段时间的坑,现总结一下,与大家分享,愿与大家一起讨论. Restful WebApi特点 WebApi相较于Asp.Net MVC/WebForm开发的特点就是前后端完全分离,后端使用W ...

  8. Java——搭建自己的RESTful API服务器(SpringBoot、Groovy)

    这又是一篇JavaWeb相关的博客,内容涉及: SpringBoot:微框架,提供快速构建服务的功能 SpringMVC:Struts的替代者 MyBatis:数据库操作库 Groovy:能与Java ...

  9. AngularJS Resource:与 RESTful API 交互

    REST(表征性状态传输,Representational State Transfer)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格.RESTful风格的设计不仅 ...

  10. Restful 介绍及SpringMVC+restful 实例讲解

    restful不是一个框架,称为一种编码更烦更贴切吧,其核心类位于spring-web.jar中,即RestTemplate.class restful是rpc通过http协议的一种实现方式,和web ...

随机推荐

  1. Linux下删除文件名带有空格的文件

    1.使用单引号将文件名括起来进行操作: rm '2018-08-07 17-29-48.png'

  2. Linux嵌入式学习-交叉编译mplayer

    http://bbs.gkong.com/archive.aspx?ID=286721

  3. stm32之定时器彻底研究

    分类: C/C++ 这里介绍两种方式使用stm32的定时器:直接操作寄存器和使用st的官方的库文件. 相比较而言,直接操作定时器比较简洁,对着寄存器看十分明了.而使用库文件有一点晕头转向. (个人观点 ...

  4. ThreadLocal源码深度剖析

    ThreadLocal源码深度剖析 ThreadLocal的作用 ThreadLocal的作用是提供线程内的局部变量,说白了,就是在各线程内部创建一个变量的副本,相比于使用各种锁机制访问变量,Thre ...

  5. Lambda 表达式实例

    public class Java8Tester {/*** 语法 lambda 表达式的语法格式如下: (parameters) -> expression 或 (parameters) -& ...

  6. 关于try catch块执行流程

    代码: package test; public class FinallyTest { public static void main(String[] args) { try { // proce ...

  7. AtCoder Beginner Contest 187 F - Close Group

    题目链接 点我跳转 题目大意 给你一张完全图,你可以删除任意数量的边 要求删除完后剩余的所有子图必须是完全图 问完全子图数量最少是多少 解题思路 定义 \(ok[i]\) 表示状态为 \(i\) 时所 ...

  8. .NET 云原生架构师训练营(模块二 基础巩固 MongoDB API实现)--学习笔记

    2.5.7 MongoDB -- API实现 问题查询单个实现 问题查询列表实现 问题跨集合查询实现 问题创建实现 问题更新实现 问题回答实现 问题评论实现 问题投票实现 回答实现 QuestionC ...

  9. Java中常用修饰符浅谈

    一.public.protected.default和private修饰符的作用域 public:在java程序中,如果将属性和方法定义为 public 类型,那么此属性和方法所在的类和及其子类,同一 ...

  10. Redis缓存篇(三)缓存污染

    上一讲介绍了缓存满了,通过内存淘汰机制来淘汰掉数据.如果有的数据一直滞留在缓存中,但又没有应用使用,时间长了,就可能会占据大部分的缓存空间. 今天我们来学习一下缓存污染,以及如何解决缓存污染. 缓存污 ...