This is a discussion that seems to reappear regularly in the SOA world. I heard it as far back as '95, but it's probably been a topic of conversation long before that. I definitely have my own opinions about it, but I'd like to hear some good, solid arguments for having a Data Services Layer, and likewise for arguments against having one.
What value does it add to a systems architecture?
What are the inherent pitfalls?
What are common anti-patterns?
Links to articles are definitely acceptable.
To avoid confusion, this article describes the type of Data Service Layer I'm talking about. Essentially, a thin layer above the database that provides SOAP access to data and includes no business logic.
Data services are quite data oriented, for projects without logic always doing crud. For instance, it can suit if you have a log service or a properties service, you will just do the crud to it.
If the domain that involves that DDBB is complex, with complex logic, you will need to manage that logic up to that service (maybe in an orchestration), so you will divide the logic into several services. In that case I think is better to use a thicker unique service (DAL, BLL and SIL) that manage that domain and expose just one interface.
At the end it is another tool, depend of the problem.
Related
I want to make an API using REST which interacts (stores) data in a database.
While I was reading some design patterns and I came across remote facade, and the book I was reading mentions that the role of this facade is to translate the course grained methods from the remote calls into fine grained local calls, and that it should not have any extra logic. As an explaination, it says that the program should still work without this facade.
Here's an example
Yet I have two questions:
Considering I also have a database, does it make sense to split the general call into specific calls for each attribute? Doesn't it make more sense to just have a general "get data" method that runs one query against the database and converts it into an usable object, to reduce the number of database calls? So instead of splitting the get address to get street, get city, get zip, make on db call for all that info.
With all this in mind, and, in my case using golang, how should the project be structured in terms of files and functions?
I will have the main file with all the endpoints from the REST API, calling the controllers that handle these requests.
I will have a set of files that define those controllers. Are these controllers the remote facade? Should those methods not have logic in that case, and just call the equivalent local methods?
Should the local methods call the database directly, or should they use some sort of helper class that accesses the database?
Assuming all questions are positive, does the following structure make sense?
Main
Controllers
Domain
Database helper
First and foremost, as Mike Amundsen has stated
Your data model is not your object model is not your resource model is not your affordance model
Jim Webber did say something very similar, that by implementing a REST architecture you have an integration model, in the form of the Web, which is governed by HTTP and the other being the domain model. Resources adept and project your domain model to the world, though there is no 1:1 mapping between the data in your database and the representations you send out. A typical REST system does have many more resources than you have DB entries in your domain model.
With that being said, it is hard to give concrete advice on how you should structure your project, especially in terms of a certain framework you want to use. In regards to Robert "Uncle Bob" C. Martin on looking at the code structure, it should tell you something about the intent of the application and not about the framework¹ you use. According to him Architecture is about intent. Though what you usually see is the default-structure imposed by a framework such as Maven, Ruby on Rails, ... For golang you should probably read through certain documentation or blogs which might or might not give you some ideas.
In terms of accessing the database you might either try to follow a micro-service architecture where each service maintains their own database or you attempt something like a distributed monolith that acts as one cohesive system and shares the database among all its parts. In case you scale to the broad and a couple of parallel services consume data, i.e. in case of a message broker, you might need a distributed lock and/or queue to guarantee that the data is not consumed by multiple instances at the same time.
What you should do, however, is design your data layer in a way that it does scale well. What many developers often forget or underestimate is the benefit they can gain from caching. Links are basically used on the Web to reference from one resource to an other and giving the relation some semantic context by the utilization of well-defined link-relation names. Link relations also allow a server to control its own namespace and change URIs as needed. But URIs are not only pointers to a resource a client can invoke but also keys for a cache. Caching can take place on multiple locations. On the server side to avoid costly calculations or look ups on the client side to avoid sending requests out in general or on intermediary hops which allow to take away pressure from heavily requested servers. Fielding made caching even a constraint that needs to be respected.
In regards to what attributes you should create queries for is totally dependent on the use case you attempt to depict. In case of the address example given it does make sense to return the address information all at once as the street or zip code is rarely queried on its own. If the address is part of some user or employee data it is more vague whether to return that information as part of the user or employee data or just as a link that should be queried on its own as part of a further request. What you return may also depend on the capabilities of the media-type client and your service agree upon (content-type negotiation).
If you implement something like a grouping for i.e. some football players and certain categories they belong to, such as their teams and whether they are offense or defense players, you might have a Team A resource that includes all of the players as embedded data. Within the DB you could have either an own table for teams and references to the respective player or the team could just be a column in the player table. We don't know and a client usually doesn't bother as well. From a design perspective you should however be aware of the benefits and consequences of including all the players at the same time in regards to providing links to the respective player or using a mixed approach of presenting some base data and a link to learn further details.
The latter approach is probably the most sensible way as this gives a client enough information to determine whether more detailed data is needed or not. If needed a simple GET request to the provided URI is enough, which might be served by a cache and thus never reach the actual server at all. The first approach has for sure the disadvantage that it doesn't reuse caching optimally and may return way more data then actually needed. The approach to include links only may not provide enough information forcing the client to perform a follow-up request to learn data about the team member. But as mentioned before, you as the service designer decide which URIs or queries are returned to the client and thus can design your system and data model accordingly.
In general what you do in a REST architecture is providing a client with choices. It is good practice to design the overall interaction flow as a state machine which is traversed through receiving requests and returning responses. As REST uses the same interaction model as the Web, it probably feels more natural to design the whole system as if you'd implement it for the Web and then apply the design to your REST system.
Whether controllers should contain business logic or not is primarily an opinionated question. As Jim Webber correctly stated, HTTP, which is the de-facto transport layer of REST, is an
application protocol whose application domain is the transfer of documents over a network. That is what HTTP does. It moves documents around. ... HTTP is an application protocol, but it is NOT YOUR application protocol.
He further points out that you have to narrow HTTP into a domain application protocol and trigger business activities as a side-effect of moving documents around the network. So, it's the side-effect of moving documents over the network that triggers your business logic. There is no straight rule whether to include business logic in your controller or not, but usually you try to keep the business logic in yet their own layer, i.e. as a service that you just invoke from within the controller. That allows to test the business logic without the need of the controller and thus without the need of a real HTTP request.
While this answer can't provide more detailed information, partly due to the broad nature of the question itself, I hope I could shed some light in what areas you should put in some thoughts and that your data model is not necessarily your resource or affordance model.
I am building simple REST deployable using Spring Boot. Decided to create it by using failing acceptance test first followed with TDD until its green.
My module is pretty simple, I have 3 API's:
Retrieving list of data from datastore.
Adds item to datastore.
Deletes item from datastore.
I feel like it is good idea to abstract datastore and have maybe backed by Map data structure for testing purposes and use it with either NoSQL or SQL db if I want to for deployments/releases and end to end testing.
On the service layer side I am unsure since it would just delegate call to repository with no logic.
So standard approach would be controller->service->repository. In my case service does not do much(possible some exception handling but not more) and I will end up with interface and implementation as an extra as well as few more lines of code. I fell like going for controller->repository solution in my situation but it is not a practice I have seen and not sure how others would see it.
What's the best way to implement this sort of system?
I feel like it is good idea to abstract datastore
You are right. The abstraction is called 'Repository' in DDD (Domain Driven Design) for example.
On the service layer side I am unsure since it would just delegate call to repository with no logic.
I'm pretty sure there are data that you want to validate. So you should have a layer in the middle (e.g. the domain layer) which will be in charge of this validation.
Even so, if you feel like your application is simple and doesn't require such layers, go without. You will have less supple design, but more simplicity at first. Be careful: while evolving your app, you could run into trouble.
Hope this will help.
This is rather an opinion based question, but if you are asking whether a 3 layer architecture is a must, to that I say no. Be pragmatic, if you don' see a reason for a class/layer/module to exist, it does not need to exist.
A repository has a purpose (to store/retrieve), and the api layer has a purpose, to offer those things through HTTP.
Here is an article for building small services with the sparkframework: https://dzone.com/articles/building-simple-restful-api
If you were to have a REST layer on top of your DDD App for CRUD, would you let the REST layer spit out domain model(in terms of data)(say for a GET)?
Generally, you'd want to be able to change your domain objects (for instance when you learn something new about the domain), without having to change a public interface/API to your system. Same thing the other way around: if a change is required to a public interface, you don't want to have to change your domain model.
So from this perspective I'd never expose my domain objects as-is over a public interface. Instead I'd create data transfer objects (DTO) that are part of the public interface. This way, changes to my domain and public api can change independently.
You should not expose the DDD model. This is absolutely correct, because a SOA frontend should not expose implementation details to clients. Your users should depend on a business function, not an implementation detail… But this assumes a nice design of several, maybe heterogeneous, applications united into a SOA bus.
I would like to add to the answer because the mention of a CRUD interface makes me think that this could be a case of SOA abuse where SOA principles are used to glue the layers of an application, instead of a network of applications. SOA is meant as a way for the enterprise to communicate its systems, it is not a way to implement MVC! So simple yet so misunderstood. For example, just because your front end GUI uses services to access the backend you do not have a "SOA application."… what ever that means.
If this is a case of SOA used to glue layers, please revise your design and use an appropriate design architecture for that level of abstraction. Otherwise you will misinterpret the recommendations found here about no exposing the DDD model and not using CRUDY, and you will surely end up creating a separate domain model for the services interface, that then you will have to map to the DDD , which is so complicated that you will need to use dozer and things like that to map the same thing with different names, and so forth until we end up with a bloated un maintainable mess…
.. just be careful.
-Alex
Redzedi is so right that we need a clarification....
Like everything, this is quite more complicated to do than to say. Serializing a complex domain model could be so difficult that you can end up either not putting any logic in the domain, the anemic model antipattern (http://martinfowler.com/bliki/AnemicDomainModel.html), or having a separate anemic model for persistence, ie DTOs.
I don’t know what is worst, but both options are bad. You should put the logic that goes in the model in the model and you should be able to serialize directly everywhere.
In my experience using the domain model for many years, I believe that the best thing is a point in the middle. Yes, as Fowler and Evans state, business objects should carry logic, but not all (http://codebetter.com/gregyoung/2009/07/15/the-anemic-domain-model-pattern/) a little anemia with a nice service layer is best.
For example, an invoice should know about its items and have a procedure to calculate its total, which depends on the items. But an invoice's item does not need to know about invoicing. So what happens when an item changes in cost, should it have a pointer back to the father invoice as a circular reference and call the invoice's calculate total procedure?
I believe not. I think that's a task for the service layer who should received the event first and then orchestrate the procedure, with out having to couple all the business objects together for implementation purposes and violating the business interaction rules, which is what a domain model is for.
-Alex
I know this might sound silly but I am finding it hard to understand the need of a service layer and its differences with business layer.
So, we are using asp.net mvc 2 and have Data Access layer which does all the querying with the database and then we have the Business Layer which has the business logic and validations needed to be done. Finally we have the Presentation Layer which basically has all the views. In addition we also have some helpers,DTOs and viewmodel classes in different folders as a part of our libraries. But I have tried to read about architecture and it seems that service layer is an important part of an architecture.
All I understand is that a service layer is something that calls all the functions.
But I can't really see the need of Service layer in our application ? Or it might be already there and I can't see it... Can anyone explain with an example how a service layer is important ? How it is different from a business layer because from what I have read seem pretty similar?
If its in the first needed at all ? All we trying to do is architect our application in the best possible way what are your thoughts and experience on it ?
It is all about decoupling your app into self contained pieces, each one defined by the requirement to do one job really well.
This allows you to apply specialised design patterns and best practices to each component.
For example, the business layer's job is to implement the business logic. Full stop. Exposing an API designed to be consumed by the presentation layer is not its "concern".
This role of the go between is best performed by a service layer. Factoring out this specialised layer allows you to apply much more specialised patterns to each individual component.
There is no need to do design things this way, but the accumulated experience of the community indicates that it results in an application that is much easier to develop and maintain because you know exactly what each component is expected to do, even before you start coding the app.
Each layer should do one job really well. The role of go between that the service layer performs is one such well defined job and that is the reason for its existence: it is a unit of complexity that is designed in the same way over and over again, rather than having to reinvent the wheel each time, to mangle this role with the business logic where it does not belong. Think of the service layer as a mapping component. It is external to the business logic and does not belong in its classes, or in the controllers either.
Also, as a result of being factored out of the business logic, you get simpler business objects that are easier to use by other applications and services that the "business" consumes.
ASP.NET MVC is nothing if not a platform to enable you to write your apps as specialised components.
As a result of this increasing understanding of how to specialise components, programs are evolving from a primordial bowl of soup and spaghetti into something different and strange. The complexity they can address, whilst still using simple structures, is increasing. Evolution is getting going. If life is anything to go by, this has to be good, so keep the ball rolling.
You might find the term Architecture Astronaut interesting.
The point is, don't get caught up in all of these "layers" that people bandy about. Every time you had another layer to the application, there has to be a purpose in it.
For example, some people successfully combine the concepts of a Data Access and Business Logic layer into one. It's not right for every solution, but it works out perfectly for a lot of them. Some people might even combine Presentation with Business... which is a major no no in a lot of circles but, again, may be perfect for the need in question.
Basically, the problem you are solving should dictate the structure of the application. If other applications need to integrate with yours, then a Service Layer may need to be added. This might take the form of simple web forms which others can post data to or it might go further to be full on web services. There might even be situations where you want the service layer to be the primary go to location for multiple presentations.
You can get as complicated as you want, but a good rule of thumb is to keep it simple until
the complications become necessary.
In some designs, the service layer is not used by the presentation layer.
The service layer is called by other applications that want to use the business and data access layers in the application.
In a way, the service layer is another front-end separate from the presentation layer.
See the architectural diagram here. The users access the application through the presentation layer. And the external systems access the application through the services layer. The presentation layer and the services layer talk to the application facade in the business layer.
As an example of what those other "external systems" might be, web services and WCF services call the service layer. Some other web application could call this application's service layer in a web service call. This would be one way to ensure that both apps are applying the same business logic, and that any changes made to the business logic are reflected in both of the apps.
As Chris Lively points out, one shouldn't get carried away with creating layers. I would recommend only creating the layers that would be useful in your application. In my experience, the need for a service layer is not frequent, but the need for a business layer is very frequent.
The Service Layer is usually constructed in terms of discrete operations that have to be supported for a client.
For example, a Service Layer may expose Creating an Account. Whereas the Business Layer may consist of validating the parameters needed in creating an account, constructing data objects to be persisted, etc.
Oftentimes, the Service Layer uses a procedural or Transaction Script style code to orchestrate the business and/or logic layers.
Knowing this, you may realize that your Business Layer really is a Service Layer as well. At some point, the point from which you're asking this question being one such point, the distinction is mostly semantic.
From my perspective a service layer allows you to isolate your presentation layer from your business layer, in the same way the business and data access layer isolates you from how you persist the data.
Inside your business layer you'd put things that are pivotal to your 'business'. A contrived (and probably poorly conceived example) would be to have that be the place where say discounting prices on a product occur.
The service layer allows you to further seperate the interface from the business. Or even swap out other business layers depending on the changing scenarios of the business.
Not every application needs one though (a lot of variables go into that determination), too much architecture can introduce complexities your team may not need.
Have a look to what Randy Stafford says about Service Layer in the "P of EAA" Book
http://martinfowler.com/eaaCatalog/serviceLayer.html
A Service Layer defines an
application's boundary [Cockburn PloP]
and its set of available operations
from the perspective of interfacing
client layers. It encapsulates the
application's business logic,
controlling transactions and
coor-dinating responses in the
implementation of its operations.
Simple. To expose your business logic to a client, use a service layer.
Ask yourself:
When changing the business logic, should the service layer change?
If the answer is "not always" then a service layer is needed.
I know this thread is old, but one useful thing I've done in the Service layer is to handle transactions (Business Layer shouldn't need to know how to handle rollbacks, ordering of operations, etc.).
Another thing I've done is used it to translate between domain entities and DTOs. The Business layer deals with the domain model, but I've passed the data back to the presentation layer in the form of DTOs (in some cases it wasn't practical to expose the whole domain model to the presentation layer for various reasons), so the service layer handles this mapping.
Ultimately, I see the business layer as more fine grained, whereas the Service layer can be more coarse in that it could call multiple operations in the BLL, and order calls within one service call.
Yes, and I would also note on that the service layer is a good place for authentication, both role based and user based.
I’m just working on this interesting thing with ADO.net entities and need your opinion. Often a solution would be created to provide a service (WCF or web service) to allow access to the DB via the entity framework, but I working on an application that runs internally and has domain access pretty much all the time. The question is if it’s good practice to create a data service for the application to interface from or could I go from the WPF application directly to the entity framework. What’s the best practice in this case and what are some of the pros’ and cons’ to the two different approach.
By using entity framework directly, do you mean that the WPF application would connect to the database, or that it would still use services but re-use the entities?
If it's the first approach, I tend to be against this because it means multiple clients connecting to the database, which a) is an additional security concern, b) could make it more expensive from a licensing perspective, and c) means you don't get the benefits of connection pooling. Databases are the most expensive things to scale so I'd try to design the solution to use services and reduce the pressure on the database. But there are times when it's appropriate. One thing I've noticed is that applications which do start out connecting directly tend to get refactored to go via a service later; it seldom happens the other way around. But it might also be a case of YAGNI.
If it's the second approach, I think that's fine. It's common for people looking at WCF to think "service oriented" - that is, there should be a strict contract between services and things shouldn't be shared. But a "multi-tier" application, which is only designed to have one client, is also a perfectly valid architecture and doesn't need to be so decoupled. In that case, reusing the entities on both sides of the service boundary should be fine. However, I'm not sure how easy this is to do with EF specifically, since I haven't used it except in experiments.
It really depends on the level of complexity and the required level of coupling/modularity. I think a good compromise would be to create a EF model in it's own library or the like with a simple level of abstraction. In that scenario if you chose to change the model to use an exposed service instead of direct access it shouldn't be a big deal to refactor existing code and the new service could utilize the existing library.