我对使用REST API构建Web服务感兴趣.我一直在阅读关于HATEOAS的内容,许多例子通过将它与人类上网时的做法进行比较来解释这个概念.这让我想到,为什么不以这样一种方式构建REST API,以便人类和机器都能轻松使用它?
例如,我有一个小部件的内部模型,这个小部件具有部件号,价格等属性.当一台机器要求一个小部件列表时,我可以返回一个JSON表示.
{
widgets: [
{
id: 1,
part_number: "FOO123",
price: 100,
url: "/widget/1"
},
{
id: 2,
part_number: "FOO456",
price: 150,
url: "/widget/2"
},
{
id: 3,
part_number: "FOO789",
price: 200,
url: "/widget/3"
},
...
]
}
Run Code Online (Sandbox Code Playgroud)
当一个人通过他/她的网络浏览器请求相同的列表时,似乎我应该能够采用相同的内部模型并对其应用不同的视图来生成HTML响应.(当然,我会用其他页面元素装饰HTML响应,比如页眉,页脚等)
这是一个明智的设计吗?为什么或者为什么不?有没有受欢迎的网站呢?
我看到的最大缺点是用户没有明显的方法来删除资源.在我的用例中,我不会让用户修改或删除资源,所以这不是一个交易破坏者,但总的来说你怎么处理?
确定 ServiceStack 实例运行的基本 URL 路径的最佳方法是什么?例如,如果我将 ServiceStack 配置为在 web.config 中的“/api”基本 URL 上运行,如何获取字符串“/api”?我想获取此值以便构建任意请求 DTO 的 URL,如 HATEOAS 样式文档。
例如,如果我有一个SomeRequest带有[Route("/someRequest")]属性的请求 DTO,则该请求的完整 URL 将是“/api/someRequest”。扩展ToUrl方法仅返回基本 URL 下面的部分路径:
new SomeRequest().ToUrl() // returns "/someRequest"
Run Code Online (Sandbox Code Playgroud)
我还没有找到任何简单的方法来做到这一点。ServiceStack 似乎没有公开返回“/api”基本路径值的配置属性。在 ServiceStack 4 中可能可以检查 web.config以获取 ServiceStack 处理程序路径,但我无法弄清楚如何使用当前的 SS 3 配置来执行此操作。
该Request.GetAbsolutePath()方法将生成当前请求的完整路径,例如“/api/someRequest”,然后我可以在它和扩展ToUrl()方法之间进行一些字符串比较来确定基本路径,但这似乎也是一个非常脆弱的解决方案。
有没有更好的方法来获取这个基本 URL?
我们可以ProductsAPI浏览我们网站上可用的产品,这些产品由我们的移动应用程序(Android 和 iOS)使用。以下是基本设计:
URL: /api/products/
Response:
[
{
"id" : 123,
"name" : "abc",
"detailsUrl" : "/api/products/123"
},
{
"id" : 124,
"name" : "xyz",
"detailsUrl" : "/api/products/124"
}
]
Run Code Online (Sandbox Code Playgroud)
此处detailsUrl包含ProductDetails页面的 API URL 。
现在,我们需要ProductDetails在新版本的应用程序中对API的响应进行一些更改,并且需要对其进行版本控制。URL 将更改为 - /api/v2/products/{id}(我们通过 URL 使用 API 版本控制)。
由于我们不想要以前版本的应用程序中的新响应,我们需要创建一个新版本的ProductsAPI也将发送新的ProductDetailsAPIurl 作为响应。
API 以这种方式耦合。如果我们更改任何子 API 的版本,则父 API 版本也需要更改。处理此问题的推荐方法是什么?我们是否应该改变我们的 API 版本控制方式(使用标头或其他东西)?
Spring Boot我正在使用,spring-data-rest-hal-browser一切似乎都很好,除了当我尝试点击 URL 时:http://localhost:8080我被重定向到http://localhost:8080/login使用 HAL 浏览器来导航我的端点,然后我看到一个屏幕,要求输入用户和密码我没有。
登录 Spring Security 的默认凭据是什么?如何更改它们或禁用登录选项?
这是我正在使用的依赖项:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这是登录屏幕:
我试图围绕如何(以及是否要)在我的api中实现HATEOAS进行研究。我喜欢这样一种概念:仅向客户提供在当前情况下适当的操作。但是我不确定我是否正确实现了这个想法。
假设我有一个资源类型订单,其状态可以更改,它可以具有不同的状态(处理中,接受,拒绝,过期,成功)。然后,我应该创建以下json对象:
{
...
"links": {
"accept": "http://example.com/order/1/accept",
"decline": "http://example.com/order/1/decline"
}
}
Run Code Online (Sandbox Code Playgroud)
还是我在这里创建不必要的动作?如果以上正确,是否应通过PATCH或GET更改状态?如果是PATCH,一个人怎么会知道(打败了超媒体的目的)?
编辑:忘记添加订单ID
According to the HAL standard (see here and here) the links to other resources should be placed in a specific embedded section.
So for instance this is not valid HAL, is my understanding correct?
{
"movies": [
{
"id": "123",
"title": "Movie title 1",
"_links": {
"subtitles": {
"href": "/movies/123/subtitles"
}
}
},{
"id": "456",
"title": "Movie title 2",
"_links": {
"subtitles": {
"href": "/movies/456/subtitles"
}
}
}
],
"_links": {
"self": {
"href": "/movies"
}
}
}
Run Code Online (Sandbox Code Playgroud)
The …
我想使用 HATEOAS 创建一个 REST API 来创建多步骤表单。每个步骤都将是一个单独的端点,提供可供选择的数据,并且在最后一步中,所有收集的数据将存储在数据库中。有什么设计模式或最佳实践吗?
谢谢你的答案。
tl; dr
我的代码从Restful GET获取了一系列javascript / json对象。如何编写代码以循环并从HATEOAS“ _link”属性检索描述(或任何值)以进行显示?
语境
我继承了一个基于Spring的小型项目,该项目跟踪服务器,软件安装等,供我们团队内部使用。它使用Angular前端和Spring / java / mysql后端实现宁静的后端。
我正在将手动编码的SQL转换为JPA和“ Spring Starter Data Rest”
目前的API
当前的手工编码SQL连接表以提供“显示友好的结果”。
Product
---------
Product ID
Product Name
Category ID
Category
---------
Category ID
Category Name
Run Code Online (Sandbox Code Playgroud)
“检索产品” sql将产品和类别连接在一起,以给出“显示友好名称”。Rest API检索带有此“类别名称”的“产品对象”。
Spring Data Rest域对象
产品
@Entity
@Table(name="products")
public class Products
{
private static final long serialVersionUID = 5697367593400296932L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public long id;
public String product_name;
@ManyToOne(optional = false,cascade= CascadeType.MERGE)
@JoinColumn(name = "category_id")
private ProductCategory productCategory;
public Products(){}
public long getId() { …Run Code Online (Sandbox Code Playgroud) javascript hateoas angularjs spring-data-rest spring-hateoas
I have a (Django) API that implements HATEOAS, so typically foreign keyed objects come through as URLs to other API endpoints. The following is the result from http://localhost:8000/brew-monitor/api/fermentations/1/ and is a Fermentation object with associated Dataset objects:
{
"id": 1,
"name": "My Beer",
"datasets": [
"http://localhost:8000/brew-monitor/api/datasets/1/",
"http://localhost:8000/brew-monitor/api/datasets/2/"
]
}
Run Code Online (Sandbox Code Playgroud)
I need to write a service that will GET the above object and then iterate through the datasets URLs and GET those as well (I know, maybe it can be more …
我正在关注一些博客和 SO 问题,他们建议Location服务器返回一个带有201 created响应的标头。Spring-data-rest还返回标头中创建的资源位置Location。
但真的有必要吗??
考虑这个POST请求:
curl -d '{..data}' -H "Content-Type: application/json" -X POST http://localhost:3000/persons
响应:
{
"name": "hero",
"_links": {
"self": {
"href": "http://localhost:8081/persons/1"
},
"person": {
"href": "http://localhost:8081/persons/1"
}
}
}
Run Code Online (Sandbox Code Playgroud)
既然响应中包含创建的资源的绝对位置self和person链接,为什么Location还需要标头呢?
我无法导入任何 HATEOAS 元素,尽管它似乎在我的 build.gradle 中正确实现:
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
Run Code Online (Sandbox Code Playgroud)
这是我的进口:
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.Resources;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
Run Code Online (Sandbox Code Playgroud)
以下是错误:
$ ./gradlew build
> Task :compileJava FAILED
path\src\main\java\payroll\EmployeeController.java:5: error: cannot find symbol
import org.springframework.hateoas.Resource;
^
symbol: class Resource
location: package org.springframework.hateoas
path\src\main\java\payroll\EmployeeController.java:6: error: cannot find symbol
import org.springframework.hateoas.Resources;
^
symbol: class Resources
location: package org.springframework.hateoas
path\src\main\java\payroll\EmployeeController.java:15: error: package org.springframework.hateoas.mvc does not exist
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
^
path\src\main\java\payroll\EmployeeController.java:41: error: cannot find …Run Code Online (Sandbox Code Playgroud) hateoas ×11
rest ×6
api ×2
hypermedia ×2
java ×2
spring-boot ×2
angularjs ×1
api-design ×1
c# ×1
gradle ×1
javascript ×1
json ×1
json-api ×1
rxjs ×1
servicestack ×1
spring ×1