REST API和DDD [英] Rest API and DDD

查看:196
本文介绍了REST API和DDD的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中使用DDD方法.

In my project using DDD methodology.

该项目具有总交易(实体).这种汇总有很多用例.

The project has the aggregate(entity) Deal. This aggregate has many of use cases.

为此,我需要创建一个rest api.

For this aggregate I need to create a rest api.

使用标准:创建和删除都没问题.

With standard: create and delete no problem.

1) CreateDealUseCase (名称,价格和许多其他参数);

1) CreateDealUseCase(name, price and many another params);

POST /rest/{version}/deals/
{ 
   'name': 'deal123',
   'price': 1234;
   'etc': 'etc'
}

2) DeleteDealUseCase (id)

DELETE /rest/{version}/deals/{id}

但是其余的用例怎么办?

But what to do with the rest of the use cases?

  • HoldDealUseCase(id,reason);
  • UnholdDealUseCase(id);
  • CompleteDealUseCase(id,以及许多其他参数);
  • CancelDealUseCase(id,amercement,reason);
  • ChangePriceUseCase(id,newPrice,原因);
  • ChangeCompletionDateUseCase(id,newDate,amercement,whyChanged);
  • etc(总共20个用例)...

有什么解决方案?

1)使用动词:

PUT /rest/{version}/deals/{id}/hold
{ 
   'reason': 'test'
}

但是!动词不能在url中使用(在REST理论中).

But! Verbs can not be used in the url(in REST theory).

2)使用完成状态(将在用例之后):

2) Use the completed state(which will be after the the use case):

PUT /rest/{version}/deals/{id}/holded
{ 
   'reason': 'test'
}

对我个人而言,它看起来很丑.也许我错了?

Personally for me it looks ugly. Maybe I'm wrong?

3)对所有操作使用1个PUT请求:

PUT /rest/{version}/deals/{id}
{ 
   'action': 'HoldDeal',
   'params': {'reason': 'test'}
}

PUT /rest/{version}/deals/{id}
{ 
   'action': 'UnholdDeal',
   'params': {}
}

在后端很难处理. 而且,难以记录.由于1动作具有多种不同的请求变体,而这些变体已经取决于特定的响应.

It is difficult to handle in the backend. Moreover, it is difficult to document. Since 1 action has many different variants of requests, from which is already dependent on specific responses.

所有解决方案都有明显的缺点.

All solutions have significant drawbacks.

我在互联网上阅读了许多有关REST的文章.到处都只有一种理论,如何解决我的具体问题?

I have read many articles about the REST on the internet. Everywhere only a theory, how to be here with my specific problem?

推荐答案

我已经在互联网上阅读了许多有关REST的文章.

I have read many articles about the REST on the internet.

根据我在这里看到的内容,您确实需要观看Jim Webber关于REST和DDD的至少一次演讲

Based on what I see here, you really need to watch at least one of Jim Webber's talks on REST and DDD

  • Rest in Practice
  • Domain Driven Design for RESTful Systems

但是其余的用例怎么办?

But what to do with the rest of the use cases?

暂时忽略API-您将如何使用HTML表单?

Ignore the API for a moment - how would you do it with HTML forms?

您大概会在一个网页上显示Deal的表示形式,并带有大量链接.一个链接会将您带到HoldDeal表单,另一个链接会将您带到ChangePrice表单,依此类推.这些表格中的每个表格都需要填写零个或多个字段,并且每个表格都将发布到某些资源中以更新域模型.

You'd presumably have a web page the presents a representation of Deal, with a bunch of links on it. One link would take you to the HoldDeal form, and another link would take you to the ChangePrice form, and so on. Each of those forms would have zero or more fields to fill in, and the forms would each post to some resource to update the domain model.

他们都将发布到同一资源吗?也许,也许不是.它们都具有相同的媒体类型,因此,如果它们都发布到相同的Web终结点,则必须在另一端进行解码.

Would they all post to the same resource? Perhaps, perhaps not. They would all have the same media type, so if they were all posting to the same web endpoint, you would have to decode the content on the other side.

考虑到这种方法,您如何实现系统?嗯,根据您的示例,媒体类型希望为json,但是其余的媒体确实没什么问题.

Given that approach, how do you implement your system? Well, the media type wants to be json, based on your examples, but there really isn't anything wrong with the rest of it.

1)使用动词:

1) Use verbs:

很好.

但是!动词不能在url中使用(在REST理论中).

But! Verbs can not be used in the url(in REST theory).

嗯...不. REST 不在乎资源标识符的拼写.有一堆URI最佳实践声称动词不好-是的,但是REST并没有这样的表现.

Um... no. REST doesn't care about the spelling of your resource identifiers. There's a bunch of URI best practices that claim that verbs are bad - that's true - but that's not something that follows from REST.

但是,如果人们是如此挑剔,则可以为命令命名端点而不是动词. (即:"hold"不是动词,而是一个用例).

But if people are being so fussy, you name the endpoint for the command instead of the verb. (ie: "hold" isn't a verb, it's a use case).

对所有操作使用1个PUT请求:

Use 1 PUT request for all operations:

老实说,那也不错.不过,您将不想共享URI(由于指定了PUT方法),而是使用模板,客户端可以在其中指定唯一的标识符.

Honestly, that one isn't bad either. You won't want to share the URI though (because of the way the PUT method is specified), but use a template where the clients can specify a unique identifier.

这是关键:您正在基于HTTP和HTTP方法构建API. HTTP是为文档传输设计的.客户会给您一个文档,描述您在域模型中请求的更改,然后您将更改应用到域(或不将更改)应用到域,然后返回另一个描述新状态的文档.

Here's the meat: you are building an API on top of HTTP and HTTP methods. HTTP is designed for document transfer. The client gives you a document, describing a requested change in your domain model, and you apply the change to the domain (or not), and return another document describing the new state.

借用CQRS词汇片刻,您正在发布命令以更新域模型.

Borrowing from the CQRS vocabulary for a moment, you are posting commands to update your domain model.

PUT /commands/{commandId}
{ 
   'deal' : dealId
   'action': 'HoldDeal',
   'params': {'reason': 'test'}
}

正当化-您正在将特定命令(具有特定ID的命令)放入命令队列中,该命令队列是一个集合.

Justification - you are putting a specific command (a command with a specific Id) into the command queue, which is a collection.

PUT /rest/{version}/deals/{dealId}/commands/{commandId}
{ 
   'action': 'HoldDeal',
   'params': {'reason': 'test'}
}

是的,也很好.

再看看RESTBucks.这是一个咖啡店协议,但是所有的api都只是传递一些小文档来推进状态机.

Take another look at RESTBucks. It's a coffee shop protocol, but all of the api is just passing small documents around to advance the state machine.

这篇关于REST API和DDD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆