The user interface is separate from the domain, but the user interface should try its best to never allow the user to issue commands that necessarily fail. Consider the following example (pseudo-code):
DiscussionController
@Security(is_logged)
@Method('POST')
@Route('addPost')
addPostToDiscussionAction(request)
discussionService.postToDiscussion(
new PostToDiscussionCommand(request.discussionId, session.myUserId, request.bodyText)
)
@Method('GET')
@Route('showDiscussion/{discussionId}')
showDiscussionAction(request)
discussionWithAllThePosts = discussionFinder.findById(request.discussionId)
canAddPostToThisDiscussion = ???
renderDiscussion(discussionWithAllThePosts, canAddPostToThisDiscussion)
PostToDiscussionCommand
constructor(discussionId, authorId, bodyText)
DiscussionApplicationService
postToDiscussion(command)
discussion = discussionRepository.get(command.discussionId)
author = collaboratorService.authorFrom(discussion.Id, command.authorId)
post = discussion.createPost(postRepository.nextIdentity(), author, command.bodyText)
postRepository.add(post)
DiscussionAggregate
constructor(discussionId, originalPoster)
createPost(postId, author, bodyText)
if (this.close && !this.originalPoster.equals(author))
throw "Discussion is closed."
return new Post(this.discussionId, postId, author, bodyText)
close()
if (this.close)
throw "Discussion already closed."
this.close = true
isClosed()
return this.close
- The user goes to
/showDiscussion/123and he sees the discussion with <form>, from which he can send a new message, but only if the discussion is not closed, or the current user has started the discussion. - Or the user goes to
/showDiscussion/123where he is presented as the REST-as-in-HATEOAS API. A hypermedia link will be provided /addPostonly if the discussion is not closed, or the authenticated user started the discussion.
?
,
canAddPostToThisDiscussion = !discussionWithAllThePosts.discussion.isClosed
&& discussionWithAllThePosts.discussion.originalPoster.id == session.currentUserId
. , , , . (, RESTBucks). - , , .
, , , , , . , , ? ? ? - ?