编排微服务的标准模式是什么?
如果微服务只知道它自己的域,但是有一个数据流需要多个服务以某种方式进行交互,那么它的方法是什么呢?
假设我们有这样的事情:
为了论证,让我们说一旦订单发货,就应该创建发票.
在某个地方,有人按下GUI中的按钮,"我已经完成了,让我们这样做!" 在一个经典的整体服务架构中,我会说有一个ESB处理这个,或者Shipment服务知道发票服务并且只是调用它.
但是,在这个勇敢的微服务新世界中,人们处理这个问题的方式是什么?
我确实认为这可以被认为是基于意见的.但是它有一个具体的方面,因为微服务不应该做上述事情.因此,必须有一个"根据定义应该做什么而不是",这不是基于意见的.
射击.
假设我想创建一个类似于以下内容的XML响应:
<?xml version="1.0" encoding="utf?8"?>
<product xmlns="urn:com.acme.prods" xmlns:atom="http://www.w3.org/2005/xlink">
<id>1234</id>
<name>Red Stapler</name>
<price currency="EUR">3.14</price>
<atom:link rel="payment" type="application/com.acme.shop+xml"
href="http://acme.com/products/1234/payment" />
</product>
Run Code Online (Sandbox Code Playgroud)
给定一个类似于以下内容的域模型:
<?php
// Product.php
namespace Acme\Bundle\ProductBundle\Entity;
use Acme\Bundle\ProductBundle\Money\Money;
class Product
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var Money
*/
private $price;
[..]
}
Run Code Online (Sandbox Code Playgroud)
和金钱类一样:
<?php
// Money.php
namespace Acme\Bundle\ProductBundle\Money;
class Money
{
/**
* @var string
*/
private $currency;
/**
*
*/
private $amount;
}
Run Code Online (Sandbox Code Playgroud)
现在,我的问题.创建如下所示的响应非常简单
<?xml version="1.0" encoding="utf?8"?>
<product>
<id>1234</id> …Run Code Online (Sandbox Code Playgroud) 我现在正在玩REST,并认为我正确地实现了HATEOAS,只是为了让所有概念都正确.
为此,我想创建自己的媒体类型(application/vnd[...]+xml和application/vnd[...]+json).
第一个问题:媒体类型是否定义了我的服务器和客户端之间的合同?
媒体类型将定义我的消息格式,因此我需要添加XML模式和JSON模式以配合新的媒体类型(以便REST客户端知道消息中的内容以及要发回的内容).
我已经在网上做了一些研究,但缺少一个人如何做到这一点的细节.它是否只涉及编写详尽的规范/文档或是否有一些技术步骤来实现?(我不需要在IANA注册吗?)
如何application/vnd创建一个全新的功能 - 媒体类型?你需要照顾什么才能让客户正确使用它?
我现在正在阅读"实践中的休息"一书.我无法理解以下术语超媒体,超媒体格式,超媒体控件,域应用程序协议.作者建议需要特定于域的超媒体格式.我很难理解那些.我搜索了这些条款,但无法找到正确的答案.任何人都可以解释这些术语以及为什么我们需要特定于域的超媒体格式而不是application/xml?
我很想知道别人如何处理为他们的网络API生成超媒体链接的问题?具体来说,我正在使用ASP.NET Web API,并且在操作返回与超媒体相关的类型,或者返回资源本身,以及在管道中稍后发生超媒体内容之间徘徊.也就是说,人们倾向于做以下事情:
public Resource<Order> GetOrder(int id) {
return new Resource<Order>() {
Content = new Order(),
Links = new LinkCollection<Order>() { new AddOrderLink(), new UpdateOrderLink()}
}
Run Code Online (Sandbox Code Playgroud)
或者更喜欢的东西
public Order GetOrder(int id) { return new Order(); }
Run Code Online (Sandbox Code Playgroud)
然后在HttpOperationHandler或自定义格式化程序或其他内容中添加超媒体链接?
如果方法更像#2,你怎么知道要生成什么链接?只是为所有Order对象生成一些标准的链接集?在OrdersController中装饰各种操作的属性?
我正处于规划REST API的早期阶段,我希望它能够遵守REST的HATEOAS约束.但我还想提供一种JSON格式.所以我的问题是,是否存在用于表示JSON中的链接和表单的约定.
我找到了链接的示例,看起来这是表示链接的一种非常常见的方式:
"links": [
{"rel": "self", "href":"http://example.org/entity/1"},
{"rel": "friends", "href":"http://example.org/entity/1/friends"}]
Run Code Online (Sandbox Code Playgroud)
另一方面,代表形式并不是我所见过的.我在想,也许有人坐下来思考这些问题,但考虑了所有的警告:
"forms" : [
{"rel" : "new client", "action" : "/clients", "method": "post",
"fields" : ["name":"string", "zipcode":"int", "signedup":"date", "state": ["Alabama",...]...]}]
Run Code Online (Sandbox Code Playgroud)
这个灵感来自于观看这个视频,其中Jon Moore认为JSON不是超媒体API的好格式:
http://oredev.org/2010/sessions/hypermedia-apis
顺便说一句真好的话题!
所有输入都表示赞赏!
我在REST上阅读的所有文章和书籍都重复了为您的超媒体响应添加"自我"重要链接的重要性,但他们对原因和用例都很清楚.
为什么要添加自我链接以及它如何有用?
所以假设我有一个现有的应用程序有两个端点/人和/裤子.呼叫GET /人员返回:
[
{
"name":"john",
"age":37,
"pants":[
{
"color":"green",
"brand":"levis",
"size":"medium"
},
{
"color":"indigo",
"brand":"jncos",
"size":"medium-with-huge-legs"
}
]
},
{
"name":"june",
"age":23,
"pants":[
{
"color":"pink",
"brand":"gap",
"size":"small"
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
如果我使用Spring Data Rest并拨打GET/person,我会收到类似的信息:
{
"_links":{
"next":{
"href":"http://myapp.com/people?page=1&size=20"
},
"self":{
"href":"http://myapp.com/people{&page,size,sort}",
"templated":true
},
"search":{
"href":"http://myapp.com/people/search"
}
},
"_embedded":{
"people":[
{
"name":"john",
"age":37,
"_links":{
"self":{
"href":"http://myapp.com/people/john"
},
"pants":{
"href":"http://myapp.com/people/john/pants"
}
}
},
{
"name":"june",
"age":23,
"_links":{
"self":{
"href":"http://myapp.com/people/june"
},
"pants":{
"href":"http://myapp.com/people/june/pants"
}
}
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
假设我有一堆我不想改变的现有客户端 - 在某些情况下是否有任何方法可以禁用响应的超媒体部分(比如Accept ="application/json")但是为了启用它们其他人(Accept …
因此,RESTful API的一般模式是返回一个带有嵌入式链接的对象,您可以使用它来检索相关对象.但有时为方便起见,您希望立即撤回对象图的整个块.
例如,假设您有一个包含客户,订单和退货的商店应用程序.您希望一起显示客户ID 12345的个人信息,所有订单和所有退货.(可能有充分理由不总是退回订单并返回客户个人信息.)
纯粹的RESTful方式是这样的:
GET /
GET /customers/12345(基于链接模板/)
GET /orders?customerId=12345(来自/customers/12345回复)
GET /returns?customerId=12345(来自/customers/12345回复)
但是,一旦你拥有了customersURI,它就能很好地将它全部拉回到一个查询中.这种便利性查询是否有最佳实践,您希望转换部分或全部链接而不是发出多个请求?我想的是:
GET /customers/12345?include=orders,returns
Run Code Online (Sandbox Code Playgroud)
但是,如果有人采用这种方式,那么我宁愿不做一些事情.
(FWIW,我不是在建一个商店,所以我们不要狡辩这些是否是这个模型的正确对象,或者你将如何深入到实际的产品或其他任何东西.)
更新添加:看起来在HAL中说这些被称为"嵌入式资源",但在所示的示例中,似乎没有任何方法可以选择嵌入哪些资源.我找到一篇博文,建议像我上面描述的那样,embed用作查询参数:
GET /ticket/12?embed=customer.name,assigned_user
Run Code Online (Sandbox Code Playgroud)
这是一个标准或半标准的做法,还是一个博主组成的东西?
我曾经暴露了在实体中用@Id注释的主键.ID字段只在资源路径上可见,但在JSON主体上不可见.
hypermedia ×10
hateoas ×7
rest ×6
c# ×1
controls ×1
embedding ×1
forms ×1
http ×1
json ×1
media ×1
spring ×1
spring-data ×1
symfony ×1
symfony-2.1 ×1