考虑以下用于联系人资源的粗粒度REST API
POST /api/contacts
GET /api/contacts
GET /api/contacts/:id
PUT /api/contacts/:id
DELETE /api/contacts/:id
考虑将事件外包用于联系人资源,即验证命令并存储事件。因此,必须存储每个事件,包括每个字段级别的更改。
CreateContactCommand -> | Contact("john", "doe", 25) | -> ContactCreatedEvent
FirstNameChangeCommand -> | Contact("jane", "doe", 25) | -> FirstNameChangedEvent
LastNameChangeCommand -> | Contact("jane", "dear", 25) | -> LastNameChangedEvent
AgeChangeCommand -> | Contact("jane", "doe", 30) | -> AgeChangedEvent
现在,结合使用REST和EventSourcing两者。
在做REST时,客户端如何与上述标准REST API通信以进行字段级别更改,以在服务器端REST端点生成命令?
主要问题是,如何设计REST API,使其也可以支持最终支持事件外包的命令?
如果有人可以阐明这一点,将不胜感激。
最佳答案
CQRS和事件源既不是API设计原则,也不是顶级体系结构。尽管如此,如果您想将API作为基于任务的API“公开”,则可以将链接公开为联系人资源的一部分。
GET /contacts/1234
响应
200 OK
<contact>
<atom:link href="/contacts/1234/first-name" rel="first-name" />
<atom:link href="/contacts/1234/last-name" rel="last-name" />
<atom:link href="/contacts/1234/age" rel="age" />
<first-name>Jane</first-name>
<last-name>Doe</last-name>
<age>25</age>
</contact>
这里的假设是您将API更改为真正的level 3 REST API。
同样,
/contacts/1234
将仅接受GET
和DELETE
(不包括PUT
)请求。如果客户想要更改,例如联系人的名字,它必须跟随关系类型为first-name
的链接,并针对该资源发出PUT
请求:PUT /contacts/1234/first-name
<first-name>John</first-name>
除了此处的
first-name
字段PUT
外,任何其他内容都应忽略或拒绝。因此,当服务收到针对名字资源的
PUT
时,它是更改联系人名字的命令。这仍然不是正确的基于任务的API,因为它无法捕获名字更改的原因,但希望您能理解。
关于api - 一起执行REST,CQRS和EventSourcing时如何在REST中支持Command?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32476397/