REA_ANDREW REA_ANDREW - 3 months ago 8
reST (reStructuredText) Question

Questioning the use of DTOs with restful service and extracting behavior from update

In the realm of DDD I like the idea of avoiding getters and setters to fully encapsulate a component, so the only interaction that is allowed is the interaction which has been built through behavior. Combining this with Event Sourcing I can get a nice history of what has been actioned and when to a component.

One thing I have been thinking about is when I want to create, for example, a restful gateway to the underlying service. For the purposes of example, lets say I have a Task object with the following methods,


  • ChangeDueDate(DateTime date)

  • ChangeDescription(string description)

  • AddTags(params string[] tags)

  • Complete()



Now obviously I will have instance variables inside this object for controlling state and events which will be fired when the relevant methods are invoked.

Going back to the REST Service, the way I see it there are 3 options:


  1. Make RPC style urls e.g.
    http://127.0.0.1/api/tasks/{taskid}/changeduedate

  2. Allow for many commands to be sent to a single endpoint e.g.:


    • URL:
      http://127.0.0.1/api/tasks/{taskid}/commands

    • This will accept a list of commands so I could send the following in the same request:


      • ChangeDueDate
        command

      • ChangeDescription
        command



  3. Make a truly RESTful verb available and I create domain logic to extract changes from a DTO and in turn translate into the relevant events required e.g.:


    • URL:
      http://127.0.0.1/api/tasks/{taskid}

    • I would use the PUT verb to send a DTO representation of a task

    • Once received I may give the DTO to the actual Task Domain Object through a method maybe called, UpdateStateFromDto

    • This would then analyse the dto and compare the matching properties to its fields to find differences and could have the relevant event which needs to be fired when it finds a difference with a particular property is found.




Looking at this now, I feel that the second option looks to be the best but I am wondering what other peoples thoughts on this are, if there is a known true restful way of dealing with this kind of problem. I know with the second option that it would be a really nice experience from a TDD point of view and also from a performance point of view as I could combine changes in behavior into a single request whilst still tracking change.

The first option would definitely be explicit but would result in more than 1 request if many behaviors needed to be invoked.

The third option does not sound bad to be but I realise it would require some thougth to come with a clean implementation that could account for different property types, nesting etc...

Thanks for your help in this, really bending my head through analysis paralysis. Would just like some advice on what others think would be the best way from the options or whether I am missing a trick.

Answer

I would say option 1. If you want your service to be RESTful then option 2 is not an option, you'd be tunneling requests.

POST /api/tasks/{taskid}/changeduedate is easy to implement, but you can also do PUT /api/tasks/{taskid}/duedate.

You can create controller resources if you want to group several procedures into one, e.g. POST /api/tasks/{taskid}/doThisAndThat, I would do that based on client usage patterns.

Do you really need to provide the ability to call any number of "behaviors" in one request? (does order matter?)

If you want to go with option 3 I would use PATCH /api/tasks/{taskid}, that way the client doesn't need to include all members in the request, only the ones that need to change.