I have created one service in my grails application. in that service 25 methods are there.
Some methods are for fetching data and passes to controller and some methods are for applying business logic and others are for database data CRUD operation.
Is it good idea to write multiple methods with different behavior to service?
and Do I have to make service transactional?
and what is the use of default method
def serviceMethod() {
}
?
this method is created when I am creating new Service...
Is it good idea to write multiple methods with different behavior to
service?
Multiple methods in a service is perfectly fine and it makes simply just makes sense if the methods in a service are related to the context.
Take for example a service called springSecurityService. You would expect the methods contained therein to be related to spring security operations. You wouldn't expect to find a sendMail method there.
Do I have to make service transactional?
You should make services transactional if in that service you perform database operation(mostly writes!). When your service is transactional you have the ability to rollback the database operation in case of a failure.
what is the use of default method
The default method is just a place holder. Feel free to edit or delete it :D
Services are transactional by default in Grails - http://grails.org/doc/latest/guide/services.html#declarativeTransactions
The serviceMethod is generated by the CreateService script. It is just an example, so you can delete it if you wish.
You could put all your business logic in services. It is convenient, but note that this is more of an anti-pattern called Anaemic Domain Model
imho, you should try to follow object-oriented principles and put most of your business processes in the domain classes. When there is a complex process involving multiple domain object, then maybe you can put this in a service.
Related
I have an authentication_service, which is required in all the services throughout the application. So, I don't want to inject this service every time (DRY). Is there a way, I can have this common service accessible from all the modules, with injecting via factory?
Thanks!!
You can use service initializers, great article with examples and more important with explained consequences:
http://www.masterzendframework.com/zend-framework/easy-setter-injection-in-zend-framework-2
I suggest you create a base service which defines all the common service requirements, such as your $authService property and the constructor that sets it. Then have your services extend that. Avoid reimplementing the constructor and property in every service to stay DRY, but injecting it via every service's factory is expected.
What actually happens when we do def someService? Does the service code get linked to the controller code?
Grails uses spring IOC, your controllers and services are managed as spring beans, when you define a service inside a controller, spring will inject the service inside the controller, code does not get linked in anyway, just reference to service will be set. Though its not a much expensive operation, you would not want to define service dependencies that are not used to keep the code clean
I think under the hood it's the same process as Spring's #Autowired annotation, so you pay a bit of a performance penalty on start up but I don't think it's significant.
There's another stackoverflow question on the subject here.
Does the service code get linked to the controller code?
That does not make sense.
Actually services in grails are singleton by default.So if you inject a Service by def serviceName it wont create a new service object but a reference to same old service object.
So its not expensive of course.
But if in a service there is a property static session="prototype" or some non-singleton like this.Then it is expensive .
What is the best way to configure a Grails service with environment specific values? I believe there are two options:
access grailsApplication values from within the service class or
configure the service bean in a beans closure in Config.groovy or resources.groovy.
I've seen a couple of posts on stackoverflow and other places that show how to do #1 (accessing grailsApplication in the service). One such post is: Inject grails application configuration into service.
However, I think this creates an unnecessary coupling of the service to Grails. Isn't this similar to accessing Spring's applicationContext in a pojo rather than configuring/injecting the values? Also, I've not had any luck getting this to work in a unit test of the service class as of yet.
Two books have examples of injecting the properties (approach #2). The book The Definitive Guide to Grails 2, chapter 10, section entitled "Services in Action" shows how to do this, but without an environment specific value. The book Groovy and Grails Recipes, section 16-2 also shows an example using resources.groovy, but I've not been able to get it to work either yet.
The following blog post also has a nice example, but not environment specific: http://ldaley.com/post/1253952347/getting-more-out-of-property-override-configuration. Chapter 15 of the Grails Reference is consistent with these examples as well and shows how to set the properties on a bean on a per environment basis.
However, none of the examples of either approach give any opinion or rational for doing it one way or another. Is there really no pros and cons to either approach? Wouldn't the injection approach be easier to unit test and more consistent with the spring way of doing things?
Nathan
I'd say use whichever you're more comfortable with. I tend to go with accessing grailsApplication.config directly from the service, because that lets you make the configuration more "semantic" (for want of a better word) in the sense that you can name the configuration options after what they do, rather than which bean they control. And if two (or more) different beans need to know the site administrator's email address (for example) then they can both read grailsApplication.config.myapp.admin.email rather than my having to configure beans.monitorService.destinationEmail and beans.userService.fromEmail separately.
In unit tests you'd have to mock the grailsApplication config anyway, so it's no big deal filling in test values for the config options your services need to read.
There's a difference in the concept of services (classes that exists in the service folder) and Spring Beans defined in resources.groovy.
To services, Grails already setup transactions:
Services are typically involved with coordinating logic between domain
classes, and hence often involved with persistence that spans large
operations. Given the nature of services, they frequently require
transactional behaviour. You can use programmatic transactions with
the withTransaction method, however this is repetitive and doesn't
fully leverage the power of Spring's underlying transaction
abstraction.
The Spring Beans that you declared aren't transactional by default.
"However, I think this creates an unnecessary coupling of the service
to Grails"
Since Grails services differ from Spring Beans I don't see a problem using approach #1.
For Unit Tests you need to manually wire up you service instance. Example:
class MyService {
def grailsApplication
}
class MyServiceTests {
MyService getServiceInstance() {
MyService myService = new MyService()
myService.grailsApplication = grailsApplication //static attribute in unit tests
return myService
}
}
Take the scenario where you have the following application:
An MVC 4 Web App
The application talks to an existing database via Entity Framework 5
(with no plans to change to another ORM or database platform).
The application talks to an external SOAP Web Service (the webservice
may change to WCF).
Would you:
Create a generic repository for all the EF entities (e.g.
MyDBRepository), and a repository for the SOAP Web Services calls
(E.g. MyWSRepository). Then create a service class that contains the
business logic uses the two repositories to access data and
implements CRUD methods for all the controller’s needs
(MyApplicationService). Then have the repositories injected into
the service class, and finally the service class injected into the
MVC controller.
Or would you have one service class that handles the db queries and
business logic using the EF generated DBContext and the generated
table entities (e.g. MyDBService), and another service class that
handles the business logic and SOAP web service calls (e.g.
MySOAPWebService). Then have both services injected into the MVC
Controllers.
Or something else.
In the past I’ve worked with option 1. But I’m wondering if that is just adding unnecessary layers of abstraction. If the Entity Framework generates a DBContext, having a service class that uses the DBContext entities directly seems to be less complex.
Having read through several articles and other questions in StackOverflow, it seems like there is a grey line differentiating the Service Locator pattern and Repository Pattern.
Which structure would you use?
I recommend a repository or DAO for each aggregate. make these classes receive the dbContext on the constructor (or unit of work if you prefer).
Then make your service implement the business logic and use the DAOs. The service is responsible for instantiating the DBContext (and a transaction if you require one). Services then call different DAOs with the same context.
For a more strong decoupling I strongly recommend that you make impossible for the service layer to touch the DBContext. Force yourself to go through the DAOs every time.
The service layer should also deal with exceptions. In my applications the service layer only throws 2 types of exception: user and system. On the controllers i use them to tell apart a recoverable error or something else. ( that's why you sometimes see specif errors like "invalid order number" or something else like "An error occurred in the system, try again later")
Btw, never forget to work with disconnected entities. when you call your repositories for add/update always assume the POCO's are disconnected and work with them accordingly.
There are two classes in my project (using ASP.NET MVC): AuthenticationService, and ProfileService.
When a new user registers at my site the Authentication controller's Register action calls a Register method in IAuthenticationService, which creates an authentication record for the user according to whichever concrete authentication module the interface is referring to (injected into the controller's constructor).
As part of the registration process a profile record is created for the user, which is created by calling CreateProfile(User) on the injected IProfileService.
At the moment the controller is calling both services, but I like the idea of my controller performing as little business logic as possible. I'm wondering if I have any other options besides letting the authentication service know about the profile service, which in turn would require any future implementation of IAuthenticationService to know to call CreateProfile? I can't help feel that has code smell written all over it.
Another possibility is to have a third service, {I,}RegistrationService, be responsible for the logic.
What's the recommended, or preferred way of handling this situation? Thanks
I like the third approach. I have a similar situation in my app where the controller needs multiple domain level services to perform a task, and the code gets a bit verbose for a controller. In particular, i have an event management system which allows for photo uploads. In addition to repositories and IAuthService, physical storage is handled by an IFileSystem (we can switch between local and S3), image manipulation by IThumbnailer, sweeping/cleanup handled by a IBackgroundTask.
What i've begun doing is create application services in addition to domain services to handle the responsibility, so that the container is now only injected primarily with app services (option 3 in your case)
I would go with an {I}RegistrationService which depends on the IAuthenticationService and IProfile services.
As a rule I aim to have a single Service Dependency per Controller
If the controller is tasked with registering users and creating profiles, whats the matter? It's OK for a controller to call multiple services. The controller serves a purpose and it doesn't have to be insanely granular.
Creating a third controller for general registration that uses an interface reference to authentication and profile would likely be the better route though. Then authentication and profiles aren't coupled.