如何构建REST风格的WEB地图服务
发布网友
发布时间:2022-04-15 22:18
我来回答
共2个回答
热心网友
时间:2022-04-15 23:47
让我们构建一个简单的EmployeeManager Web服务,我们将使用它来演示与MongoDB连接的HATEOAS。为了引导我们的应用程序,我们将使用Spring Initializr。我们将使用Spring HATEOAS和Spring Data MongoDB作为依赖项。你应该看到类似下图2所示的内容。 图2 :引导应用程序配置完成后,下载zip并将其作为Maven项目导入你喜欢的IDE中。 首先,让我们配置application.properties。
spring.data.mongodb.host= //Mongo server host
spring.data.mongodb.port= //Mongo server port
spring.data.mongodb.username= //Login user
spring.data.mongodb.password= //Password
spring.data.mongodb.database= //Database name
一般来说,如果所有内容都是全新安装的,并且你没有更改或修改任何Mongo属性,则只需提供一个数据库名称(已经通过GUI创建了一个数据库名称)。
spring.data.mongodb.database = EmployeeManager
另外,为了启动Mongo实例,作者创建了一个.bat,它指向安装文件夹和数据文件夹。它是这样的:"C:\Program Files\MongoDB\Server\3.6\bin\mongod" --dbpath D:\Inther\EmployeeManager\warehouse-data\db
现在,我们来快速创建模型。这里有两个模型,员工模型和部门模型。检查它们,确保有没有参数、getter、setter、equals方法和hashCode生成的构造函数。(不用担心,所有代码都在GitHub上,你可以稍后查看它:https://github.com/theFaustus/EmployeeManager。)
public class Employee {
private String employeeId;
private String firstName;
private String lastName;
private int age;
}
public class Department {
private String department;
private String name;
private String description;
private List<Employee> employees;
}
现在我们已经完成了模型的制作,让我们来创建存储库,以便来测试持久性。存储库如下所示:
public interface EmployeeRepository
extends MongoRepository<Employee, String> {
}
public interface DepartmentRepository
extends MongoRepository<Department,String>{
}
如上所示,这里没有方法,因为大家都知道Spring Data中的中心接口被命名为Repository,在其之上是CrudRepository,它提供了处理模型的基本操作。在CrudRepository之上,我们有PagingAndSortingRepository,它为我们提供了一些扩展功能,来简化分页和排序访问。在我们的案例中,最重要的是MongoRepository,它用于严格处理我们的Mongo实例。因此,对于我们的案例来说,除了那些现成的方法外,我们不需要任何其他方法,但是仅出于学习目的,作者在这里要提到的是你可以添加其他查询方法的两种方法:
“惰性”(查询创建):此策略将尝试通过分析查询方法的名称并推断关键字(例如findByLastnameAndFirstname)来构建查询。编写查询:这里没有什么特别的。例如,只用@Query注释你的方法,然后自己编写查询。你也可以在MongoDB中编写查询。下面是基于JSON的查询方法的示例:@Query("{ 'firstname' : ?0 }")
List<Employee> findByTheEmployeesFirstname(String firstname);
至此,我们已经可以测试我们持久性如何工作。我们只需要对模型进行一些调整即可。通过调整,作者的意思是我们需要注释一些东西。Spring Data MongoDB使用MappingMongoConverter将对象映射到文档,下面是我们将要使用的一些注释:@Id :字段级别注释,指出你的哪个字段是身份标识。@Document :类级别的注释,用于表示该类将被持久化到数据库中。@DBRef :描述参考性的字段级别注释。注释完成后,我们可以使用CommandLineRunner获取数据库中的一些数据,CommandLineRunner是一个接口,用于在应用程序完全启动时(即在run()方法之前)运行代码段。我们已经创建了一些模型,并对它们进行了持久化。现在,我们需要一种与他们交互的方式。如上所说,所有代码都可以在GitHub上找到,因此作者在这里将仅向我们展示一个域服务(接口和实现)。接口的实现如下:@Service public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
@Override
public Employee saveEmployee(Employee e) {
return employeeRepository.save(e);
}
@Override
public Employee findByEmployeeId(String employeeId) {
return employeeRepository.findOne(employeeId);
}
@Override
public void deleteByEmployeeId(String employeeId) {
employeeRepository.delete(employeeId);
}
@Override
public void updateEmployee(Employee e) {
employeeRepository.save(e);
}
@Override
public boolean employeeExists(Employee e) {
return employeeRepository.exists(Example.of(e));
}
@Override
public List<Employee> findAll() {
return employeeRepository.findAll();
}
@Override
public void deleteAll() {
employeeRepository.deleteAll();
}
}
这里没有什么特别的要注意的,下面我们将继续讨论最后一个难题——控制器!因此,对于上面实现的所有方法,我们将自己定位在Richardson成熟度模型的第二级,因为我们使用了HTTP动词并实现了CRUD操作。现在,我们有了与数据进行交互的方法,并且可以使用Postman,我们可以如下图3所示检索资源,或者可以如下图4所示添加新资源。 图3 :检索JSON中的部门列表 图4:JSON中添加新员工
热心网友
时间:2022-04-16 01:05
REST英文全称为Representational State Transfer(表述性状态迁移),是2000年Roy Thomas Fielding博士在他的毕业论文中首次提出的概念,国内一帮精英已经把Fielding的论文翻成了中文,但是看完论文还是很难搞清REST到底是什么。Leonard Richardson与Sam Ruby的新书《RESTful Web Services》对REST作了简单而具体的诠释,提出了面向资源架构(The Resource-Oriented Architecture)的设计方法。根据对书中内容的理解,我这里作一简单的总结,不一定对,仅供参考。
1 什么是REST
REST是一组设计原则,或说是一种风格,不是架构,Fielding在他的论文中表示符合REST原则的web服务将在可见性、可靠性与可伸缩性等方面获益,而且符合万维网创建的初衷。
Google map(http://maps.google.com/)就是REST风格的web服务一例,当光标热点移动时,左下角随之变化的URI可以看出它是根据URI在提供相应的web服务。
REST是一组广义的设计原则,REST本身并没有与Web、HTTP或URI绑定,REST设计原则包括客户-服务器、无状态、缓存、统一接口、分层系统等。既然原则中要求无状态,又何来表述性状态呢?REST原则的无状态指服务器端不保存客户应用状态,连接→请求→响应→断开,客户的上一次请求与下一个请求没有关系(这其实是HTTP的特征)。服务器端响应客户请求返回资源的表述及相关链接(想像一下google返回的页面),该表述的本身就是客户的当前状态,客户按照表述中提供的链接选择下一个表述,迁移到下一个状态。这是我从字面上对REST的解释,也就是服务器通过表述为状态迁移提供指导,而状态的迁移权掌控在用户手里,客户根据自己的需要选择链接,由当前状态迁移到下一个状态。这个解释很肤浅,下面的面向资源架构从根本上对REST作了技术上的诠释。
2 面向资源架构
面向资源架构是一种REST风格的架构,它以资源为研究对象,通过划分资源、定义资源,然后用超媒体将资源串起来,提供客户所需求的服务。面向资源架构包括四个组成元素,具有四个属性。四个组成元素是:资源、资源名、资源表述和链接。四个属性是:可寻址、无状态、连通和统一接口。
2.1 四个元素
(1) 资源
就象面向对象设计取决于问题域对象划分一样,面向资源设计的首要任务就是划分资源,实际上面向资源是极端的面向对象,因为REST中规定了统一接口约束,要求对资源的操作必须是可见的(如HTTP中标准的GET、PUT、DELETE、POST,带暗箱操作的POST不算),因此资源的操作方法是不能自行定义的。
在面向资源设计中的资源可以是任何具有超文本链接价值的东西,资源可以是数据资源,也可以是物理对象,物理对象本身不能在网上传输,但物理对象的元数据可以。当统一接口方法不能满足需求时,可以通过设计资源将操作名词化,例如你“订阅”某个栏目,统一接口中没有“订阅”操作,也不允许你自行定义“订阅”操作,怎么办呢?你可以将“订阅”设计为资源“订阅关系”,“订阅关系”就可以用统一接口中的方法,如GET、PUT、DELETE进行操作了。同样,对于需要异步完成的操作,也可以通过资源将异步操作划分为多个同步操作来完成。总之,资源可以是任何东西,遇到困惑时可以设法通过资源来解决。
(2) 资源名
资源能成为资源的必要条件是:每个资源必须用URI唯一标识。这符合Tim Berners-Lee公理:Web上每一个资源由URL唯一确定。超文本系统、HTTP 和Internet分层协议之间是不能交流的,URI把所有这些协议集成到了web中。资源用URI命名,资源通过URI定位,URI中不仅包含资源的地址,还包含对资源的操作指令,服务器端根据URI中的指令确定客户请求的处理方式。因此,这里的URI不是单纯的网址。
(3) 资源表述
资源是表述的数据源,表述是资源的当前状态(应客户请求返回的网页),对REST风格的服务来说表述是超媒体,表述中不仅包含着当前资源的信息,还包含了相关资源的链接。
因此,表述呈现了资源的当前状态,也链接着资源的其它状态。表述具体涉及资源的数据及数据格式。可用于表述的超媒体格式有多种,如: 应用/XHTML+XML、应用/ATOM+XML、图像/SVG+XML、应用/JSON、应用/WADL+XML。《RESTful Web Services》书中对WADL(Web Application Description Language,https://wadl.dev.java.net)较为推崇,WADL是用于描述HTTP资源特征的XML格式定义(词汇表),书中认为WADL剥离了HTTP请求和响应(表述的建造与解析)的细节,支持URI模板及HTTP统一接口,可以特定符合XML Schema定义的XML表述格式,可简化web服务的客户端编程,与其它超媒体格式相比,WADL有其独特的优点。
(4) 资源链接
资源不是孤立的,是可以连通的,资源通过Link或Form链接,Link与Form本身就是资源表述的一种,因此说表述是超媒体。
2.2 四个属性
(1) 可寻址
每个资源由唯一的URI标识,使资源可定位,也因此使缓存成为可能。
(2) 无状态
客户请求与服务响应通过HTTP 通信,HTTP本身是无状态的,HTTP请求在完全封闭的过程中完成,请求中包含了服务器完成请求所必需的全部信息,请求与请求之间没有关联。这样,服务器端无需等待、无需追踪,它只需要关心客户发送请求时的应用状态就足够了。服务器端的服务之间也不需要分工协作,服务扩展只是将服务插入负载均衡器就行了,这样就增强了服务的伸缩性能。
REST 中的无状态是指仅有一种状态,该状态不在服务器端而在客户端。其实,从资源角度来说,服务器端也有状态,那就是资源状态。服务器应客户请求返回资源的表述,资源通过HTTP由资源状态迁移到客户应用状态;客户向服务器上传资源表述(例如Amazon的S3服务),客户应用状态通过HTTP迁移到服务器变成了资源状态,这是不是应该是REST的真正含义?
(3) 连通
资源应该以某种方式连通,也就是资源是链接的,不需要用户在浏览器中键入URI执行跳转。Link或Form链接是资源连通的超媒体。
(4) 统一接口
面向资源架构利用了HTTP的统一接口,HTTP统一接口提供了四种基本操作方法GET、PUT、DELETE和POST,面向资源架构要求所有服务按HTTP标准方式使用GET、PUT、DELETE和POST,这样安全性好,没有副作用产生,其次响应结果具幂等性(数学上术语),即同一请求返回的结果总是相同的(如:任何数不管乘零多少次结果总是零),除非底层资源发生变化。
3 以一个Web地图服务为例
这是《RESTful Web Services》书中一个最简单的例子,因为Web地图是只读的服务。我只是简单总结,以便大家对REST风格的架构有一个直观的认识。
设计步骤如下:
l 分析数据集
l 将数据集划分为资源
对每一个资源
l 用URI给资源定名
l 选择统一接口方法
l 设计客户端→服务器的表述
l 设计服务器→客户端的表述
l 用超媒体链接或表单将资源挂接到现有资源链中
l 正面设想一下该发生什么
l 反面设想一下什么可能发生
(1) 分析数据集
本数据集为各大星球二维平面图,可以通过地理坐标及地名在地图上定位,并展示以点为中心的平面图。
(2) 将数据集划分为资源
资源大体分三类:
l 预定义的一次性资源,如同一个web主页,充当其它资源的顶级入口。你能GET它,但不能DELETE或PUT它。
l 每个对象的资源,每个对象有自己的资源集合,你可以GET、DELETE或PUT对象的资源。
l 经数据处理后获取的资源,例如根据查询条件返回的结果。