I am designing a REST API coupled with a service layer that takes DTOs as input and produces them as output. This works fine for most service calls where the DTO is used to access an underlying library (an embedded OLAP server) that does the work.
There is one service, however, where something seems wrong. The service is responsible for creating, manipulating, and optionally storing objects that represent reports (think excel reports). It does this through the underlying library, which does not expose reports as a resource. Since the reports don't represent a server-side resource unless they are persisted (persistence being my own implementation, not a concept in the library), the service needs to take a report object that holds all the information necessary to construct a report from scratch to be stateless.
I decided that the report service methods should take a ReportDTO, manipulate it, and return the modified version. (This would include operations such as swapping the row and column axes, sorting an axis, and filtering an axis.) My thinking was that since I have all the information available in the ReportDTO necessary to perform all these operations, I might as well perform them on the DTO and return a modified version rather than duplicate the DTO as a domain object. That is not to say the server doesn't interface with any model. Indeed, the server-side code involves validating the report using a third party library (i.e., the validation model is not my own -- i don't have a domain model for the report itself, just DTOs), saving the report if the user so chooses, and executing the report against a database to obtain fresh data. So there is work to be done besides manipulating DTOs, it's just that it's not work tied to a domain model I needed to design myself, but rather one provided to me.
After I implemented the aforementioned operations, I realized something. The operations are business logic operations, are they not? A DTO should not have this. I then had numerous other thoughts: "Okay, that's fine, I'll do the operations in the service layer... Oh, wait. The service layer should only coordinate domain objects that contain business logic, not have business logic itself. Alright, I'll make the ReportDTO a bonafide domain object. Crap, now I am exposing my domain objects from the service layer. This is an API, I should really stick with DTOs as the input and output for the service layer so that changes in my domain model (or changes in the 3rd party domain model I utilize) do not affect the contract with service clients. Fine, I'll have a Report and a ReportDTO.... that have exactly the same members because the ReportDTO already has all the necessary information to manipulate a report (just not execute, validate, or save it) due to the transient report decision I made for the sake of a RESTful API."
Clearly I have countered my every proposed solution. So, what the heck do I do? I don't want to make reports stateful because I really don't see them as a resource until they are actually saved. If I make them stateful I'll need to manage a map or cache of them in my service and deal with multiple clients trying to give their report the same name, implement security to ensure that a user can only see his own reports, etc. All these problems go away with a stateless approach. The side effects, however, are the aforementioned issues. Did I go wrong somewhere? Please help me tackle this design issue before it becomes a permanent part of my API. Thanks.