We are in the design phase of setting up an internal enterprise API layer for our company. We are hoping to realize an API that can serve our internal apps as well as our external clients. Our environment is MS heavy, IIS, ASP.NET MVC apps, etc.
We have an existing service layer that was not designed well, so we are trying to do it right this time.
This question indicated a project breakdown for larger ServiceStack projects that is no longer present in the main documentation. Primarily the inclusion of a separate "Logic" project. We are trying to align this with a lot of what Martin Fowler outlines in Patterns of Enterprise Application Architecture.
Here is what we are considering:
○ Service.Host (single)
§ Dumb Host
§ Assigned multiple Service Interfaces on startup (subsystems)
○ Service.Interfaces (many projects)
§ Subsystems of Business (e.g. Ordering, Customers, etc)
§ Data Access Layer with Repository pattern
§ Service Layer endpoints
□ Application endpoints (returns data/dtos for views/screens)
□ Vendor Endpoints (Feeds, hierarchies, etc; authentication/authorization)
○ Service.Models (single)
§ DTOs for all systems (namespaced appropriately?)
§ Shared and distributed to vendors/client apps
§ No dependencies
○ Service.Logic
§ Rich Domain Layer
□ Objects that model our business
□ Rules/algorithms for business logic
○ Service.Tests
Fowler and other suggest that DTOs and Business Logic should be independent of each other, with Assembly/Factory classes that convert between.
First question: Where do the assemblers live? In the Service Interfaces project? In their own project? Are they necessary for every conversion?
Secondly: Does the client need to convert back to Domain Objects, or does the client just use DTOs to populate screens and send data back to the service? We only want clients dependent on the Service Models class, right?
Thirdly: How do we design the DTOs? Previously, they were pocos that represent one resource (trying to be restful, OrderDTO, CustomerDTO, etc). In practice the data required is complex. We initially thought the clients request whatever they need individually and piece it back together. Fowler indicates that we want to minimize requests to the service, and have dtos that are almost aggregates of the business objects, to try and send it all down at once. So if I have an order and a want the customer tied to it, should I send down a CustomerOrderDTO with everything populated? Or do I send down an order object, and force the client to make another request for the order?
Fourth: Where is it appropriate to use actual C# interfaces? Do we have one for every repository to make them switchable and testable? One for every service interface?
Fifth: Is there no choice but to map at every layer? i.e. SQL to Data layer using ORM. Data Layer to Domain Layer using AutoMapper or ServiceStack mapper. Domain layer to DTO. DTO to ViewModel. ViewModel to Javascript model (e.g. Knockout) It seems like a lot of repetition and boilerplate. Is there a better way?
I'm trying not to make this subjective - but there are very little guidelines for some of the details here - our assumption is there are best practices or intentions that we are missing in the ServiceStack framework to account for these things. Thanks in advance for answering any of these questions.