Service call back to a Controller? - grails

Grails makes it very easy for a Controller to call into a Service and for a Controller to forward a request onto another Controller.
So suppose you have a service method as such
List<String> updateNames() {
...
}
You can call it very easily from any controller.
I am wondering, say if you have an edge case where you realise there is a validation problem in your service method. You don't want to throw an Exception back to your controller, because it is not really an exceptional case. But you can't return back an error message from your Service to the Controller that called because that will mean you have to use some wrapper object instead of a nice List
Is there anyway for these cases, you can get the Service to do a server side forward onto another Controller which could return an Error response to user?
Thanks.

Grails already have a structure for validation in your beans, called Errors (comming form Spring). For example, if you have a service to upload files, you could easily attach validation errors in your bean:
class UploadService {
void doUpload(MultipartFile file, MyDomainClass domainClassInstance) {
if(validationsFail) {
domainClassInstance.errors.rejectValue("myUploadField","my.i18n.code")
}
}
}
If it's not a domain class, you can consider using a command object since they're validateable too.
In your controller, it's just a metter of checking if your instance has errors:
def upload() {
MyDomainClass instance = ...
uploadService.doUpload(request.getFile('file'), instance)
if(!instance.hasErrors()) {
//save and go on...
}
}
Another option is to work with exceptions like #Joshua Moore answered. Just remember to extend RuntimeException. If you don't, your transaction will not be rolledback automatically.

Services are not aware of the web/http request context in this way. I won't get into how this line is blurred with session or request scoped services since it still doesn't apply to what you are asking about. Plus, you really don't want your service to even be aware that it's dealing with a web/http request, since you want to separate responsibilities and have a good/clean design.
So, back to your question. This is exactly the case for raising an exception from your service and letting your controller handle the result of that exception. If it's a validation error on an instance then you should be able to access the errors collection of the instance in your controller (provided of course that it was an input into your service).
As a side note about exceptions from services. Stack traces are expensive to fill in. This is even more so in Grails since there are a lot of pieces at work. I highly recommend if you are going to raise your own business logic exceptions from your services that you override the fillInStackTrace method on your exception to avoid this cost.
Here is an example:
package com.example
class MyBusinessException extends RuntimeException {
List<String> argList = []
public MyBusinessException (String message, List<String> args){
super(message)
argList = args
}
public MyBusinessException (String message){
super(message)
}
/**
* Don't fill in the stack trace because we want things to be faster.
**/
#Override
public Throwable fillInStackTrace() {
// do nothing
return this
}
}

Related

Exception Handling in webapi MVC.net

I got an API with a controller and a service, when invoking one of the action in the controller I must apply a validation, this validation need to check the data in DB to validate that is correct.
As far as I can see there are two ways of handling this
1- Validate before calling the "update" to prevent the error
public IActionResult UpdateCustomer(CustomerDto customer)
{
if (!customerService.Validate(customer))
{
return Send400BadRequest();
}
customerService.Update(customer);
return Send200Ok();
}
2- Call the update validate inside and throw an Exception.
public IActionResult UpdateCustomer(CustomerDto customer)
{
customerService.Update(customer);
return Send200Ok();
}
In customer service
public void Update(CustomerDto customer)
{
if (!Validate(customer)
throws new CustomValidationException("Customer is not valid");
//Apply update
}
We already have an ActionFilter to handle the CustomValidationException so it will return a BadRequest.
1)
Pros
+Don't use Exception to use the running flow
Cons
-Controller is more fat, has more decision on each case it will decide which is the output
2)
Pros
+Operation is more atomic, all logic is inside the service.
+Easier to test
+Every use of the method will be validated.
Cons
-Use exception to manage the flow.
Which is a better solution?
I really need arguments to defend one or the other.
If you have a Business Logic Layer and a Service Layer, I prefer to keep all Business Logic Rules including Business Logic Validations in Business Logic Layer and use Service Layer as a wrapper around Business Logic Layer and throw Exception in Business methods.
When deciding about whether to use Exception for Business Validation rules or not, you can consider:
1) It's better that your Business methods be a Unit of Work. They should perform a complete task. So it's better they contain also validation rules. This way you can reuse such Business Logic Layer across different Service Layers or use the same Unit of Work in different methods of the same Service Layer. If you throw a Business Validation Exception in Business Logic Layer, you will not face with risk of forgetting validation or using another validation rule by mistake and each service method / action will perform a single task for you and will be as lightweight as possible.
Think about when you may need to expose a WCF service for some clients or for example if you may use ASP.NET MVC without using WebAPI or iff you want to use the same logic in another Action method in the same WebAPI.
If you put Business Logic validations in Web API controller, when creating WCF service methods or creating MVC Actions or other service methods, you may forget to apply validations or may apply wrong validations with different rules in the new Service Layer.
2) Considering the first benefit, can you return a meaningful value from methods that shows success, failure, or contain suitable information about failure reason in output?
I believe it's not suitable to use out put of method for all these goals. The method output is method output, it should be data in such business application. It should not be sometimes a status, sometimes data or some times message. Throwing exception will solve this problem.
I am going against the other opinions on here and saying that the first method both clearly illustrates what the intent of your method is and if you ever decide to not return a 400 error, its a bit easier to pull that off in scenario #1.
Additionally, some thoughts on exceptions. Exceptions should be exceptional, meaning unexpected events that occur in your code. A company not passing a validation check is not an exception-al event, it either does pass or does not pass. Passing a User object into the ValidateCompany() method should throw an exception.
Here is a good answer on the similar topic of exception throwing. It uses an easy example problem to determine when in that case an exception should be thrown or not.
In regards to "Easier to test" - I don't see how. Your controller will have two tests with any option you choose, a valid company and an invalid company. Your service will have two tests with any option you choose, a valid company and an invalid company (obviously simplifying your service layer a bit here). In any case you want to ensure both your controller action and your service layer can handle an invalid and valid company object.
I would prefer 2 :)
Because I think service might be called from another node not only the asp.net controller so it would be nice for me if all validation logic is handled in the single layer like Service layer.
i think handling exception by using httpresponse message is much better then any one else. Atleast you got the proper error response with proper http response message as output.
public HttpResponseMessage TestException()
{
try
{
//if your code works well
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.ExpectationFailed, ex.ToString());
}
}
I would do it this way:
public IActionResult UpdateCustomer(CustomerDto customer)
{
try
{
consumerService.Update (customer);
}
catch (CustomValidationException)
{
return Send400BadRequest ();
}
return Send200Ok ();
}
And in your CustomerService:
public void Update(CustomerDto customer)
{
if (!Validate(customer))
throw new CustomValidationException("Customer is not valid");
}
This way your service has the validation logic. So any other callers to your service will also have their inputs validated before attempting an update and hence will get proper error messages.
Your controller will not have any validation code. And moreover, having the try-catch block means you can gracefully handle any other errors the Update call might throw. Hope that helps.
Receive a validatable customer model, pass this model to the data service layer, and perform exception
handling in the controller if the data service layer fails.
Customer model
Implement IValidatableObject to trap business logic related errors.
public class CustomerModel : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// example validation
if ( Balance < 100 )
yield return new ValidationResult("Balance >= 100 req.", new [] { nameof(Balance) });
}
public string Name { get; set; }
public double Balance { get; set; }
}
API Controller
Receive a CustomerModel in your public facing UpdateCustomer API method, then reference ModelState to determine if the customer is valid.
public IActionResult UpdateCustomer(CustomerModel customer)
{
if(ModelState.IsValid) // model validation succeeded
{
try
{
customerService.Update(customer);
}
catch (ServiceUpdateException svcEx)
{
// handled failure at the service layer
return Conflict();
}
catch (Exception ex)
{
// unhandled error occured
return InternalServerError(ex);
}
// update succeeded
return Ok();
}
// invalid model state
return BadRequest();
}
Service (Data Layer)
public void Update(Customer customer)
{
//Apply update
try
{
database.Update(customer);
}
catch (DataStorageException dbEx)
{
throw new ServiceUpdateException(dbEx);
}
catch
{
throw;//unknown exception
}
}
I think that you should validate in both the controller and the service, but validate slightly different things. Especially if what starts off as just an api turns into an api, with a mvc site and a wpf admin interface as often happens.
Using Validation Attributes and Model Binding gives the data a quick "once over" check. Did they supply the id for the customer to update? Did they submit foreign key value for a related entity? Is the price between 0 and 1,000,000? If you have a website then you also get client validation out of the box. Crucially there no need to connect to the database at all, as the data is "obviously" wrong.
Validation in the service is also required as you may end up with 3 or 4 applications calling this service, and you want to write the business logic once. Some validation eg. referencing foreign keys can only be done in the database, but there is nothing wrong in throwing an exception. Consumers of your api should have access to the range of valid values, users of the website should be choosing from a drop down etc, so this circumstance should be exceptional

ASP.net Web API - Generic 404 handling

Is there a way to handle 404 (resource not found) generically, or do I have to write logic for each action? A simple example of what I am currently doing:
//single-read
public HttpResponseMessage Get(Guid guid)
{
School school = new School(guid);
if (school == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
//bonus-question: would it be better to instead: throw new HttpResponseException(HttpStatusCode.NotFound);
}
//bonus-bonus-question: what is the benefit of using a typed response?
return Request.CreateResponse<School>(HttpStatusCode.OK, school);
}
If possible, I would like the "not found" logic to be handled elsewhere so that I didn't need to repeat those few lines of checking for each action. For example, I'd like it if it could be reduced to:
//single-read
public HttpResponseMessage Get(Guid guid)
{
School school = new School(guid);
return Request.CreateResponse<School>(HttpStatusCode.OK, school);
}
You can implement an IActionFilter on your controller which will be called everytime an action is about to be executed and also when an action has finished execution. You can then perform your checking logic there. See documentation. You would annotate the controller class itself with your filter and it would be called for all actions.
In terms of the error handling, if you don't throw an exception, then you won't pay the cost of exceptions (which I'd like to pretend to be negligible), but more importantly, you won't allow any exception handlers to kick in and that may be something you actually want. Take a look at IExceptionFilter for example that gets called whenever an exception is thrown. If there is a part of your application that relies on that (for example logging errors), that component won't know that there was an error when you don't throw an exception, so it's a design call.

Grails - controllers and tight coupling with backend

When you generate controllers in grails, the controllers call methods on the domain layer directly - I quite don't understand this, every bit of me is telling me that this is kind of wrong because you are tightly coupling the backend with the frontend. I think this belongs to the service layer.
Since it would be pretty ugly to create an equivalent set of methods in the service layer for all the methods defined on domain objects, I created this AbstractService to delegate all (missing) method calls from the service layer to the domain layer:
abstract class AbstractService {
def entityType
/**
* By default, this method takes the name of the service that extends this
* class, removes the suffix 'Service' and tries to create the Class object
* from the resulting name. Override at will.
*/
protected Class getEntityType() {
if (!entityType) {
try {
entityType = Class.forName(this.class.name[0..-8], false, Thread.currentThread().contextClassLoader)
} catch (ClassNotFoundException e) {
throw new ClassNotFoundException("Class ${this.class.name[0..-8]} could not be found. Please "
+ "override AbstractService#getEntityType() for ${this.class}.")
}
}
entityType
}
def methodMissing(String name, args) {
try {
if (getEntityType()?.metaClass?.getStaticMetaMethod(name)) {
getEntityType().invokeMethod(name, args)
} else if (args?.last()?.metaClass?.getMetaMethod(name)) {
args.last().invokeMethod(name, args.take(args.size() - 1))
} else {
throw new MissingMethodException(name, this.class, args)
}
} catch (MissingMethodException e) {
throw new MissingMethodException(name, this.class, args)
}
}
}
Then I just extend this service e.g. like this:
class UserService extends AbstractService {
}
And my controllers then can look for example like this:
class UserController {
def userService
def create() {
userService.save(new User(params))
}
def list() {
userService.list(params)
}
// et cetera...
}
Don't you think this is better? Thanks to dependency injection, I can for example rewrite the whole business layer without the need to change the code in the controllers - which is kind of why we use dependency injection, isn't it?
Thanks for your answers, I would like to hear as much opinions as possible.
This model is very used in Java Web applications and all. The Rails (and Grails followed it) community just tried to break the paradigm here, leaving it more simple. I mean, why would you delegate a service class to manipulate an entity, if this entity can simply do the job? If it's natural to the entity to do the job, then don't bring someone else to do it. That way, you avoid the Anemic Model since your objects are not only data holders, but they also know how to operate its own business.
Having said that, there are times when you're better off using a service class to do operations on your entities. For example, if it involves different kind of entities at the same time and so on... So, when it's not "natural" (and you would have to force to make it work) for the entity itself to take care of the operation, then a service class is the way to go. This article based on Rails gives some tips about the use of a service class.
And you are not tightly coupling the controller with the models (you said backend and front end, but I guess that's what you mean). The controller will eventually need to use the model, be it the entity itself or a service class (also Model) manipulating it.
The scaffolded controller code does not really represent ideal application architecture. Keep in mind that the generated scaffold code is just a starting point for generating the CRUD portions of your application.
You are correct that in general, you don't want to put most of your GORM queries in Controllers, since controllers are supposed to be for interacting with the front end. You can certainly either put the query/business logic into Services or put the queries directly into Domain classes. That's why Grails Services support declarative transaction handling.

Grails: Prevent further code execution after a redirect or forward in base class of a controller

I have following controller structure:
abstract class AbstractController {
// ...
}
abstract class AbstractDiagramController extends AbstractController {
// ...
}
class PopulationController extends AbstractDiagramController {
// ...
}
Most controller-actions call various methods of the abstract base classes. If now one of these base-methods needs to send a redirect (or forward) to the client, Grails won't prevent the application from processing the remaining action code of the controller-action anyway.
From my point of view this is an undesirable behaviour, due the base-methods do some kind of validation (like validating parameter, user, session etc), and the controller assumes that the validation succeeded (thence produces subsequent errors).
How can i prevent this insufficient behaviour?
Kind regards,
Christopher
PS: I found already this question, but the answers did not satisfy my needs, because none of them deal with a base controller:
PPS: I am using Grails in version 1.3.7
EDIT
This is a reaction of Victor Sergienko's comments.
Here I give a more detailled code-example of my problem.
// The very base controller
abstract class AbstractController {
// The interceptor gets called before any action of inheritors get processed
def beforeInterceptor = [action:this.&initialize]
// Method validates various stuff
protected initialize() {
if( someThingIsWrong() ) {
// This redirect should stop any other code of inheritors
redirect( controller: "foo", action: "bar" )
return false
}
}
}
// The second base controller
abstract class AbstractDiagramController extends AbstractController {
// This object must get initialized. If not (eg any errors or exceptions occured)
// all inheritors actions are not allowed to do anything
MyObject myGreatObject = null
// Overriden, because of additional individual diagram validation
#Override
protected initialize() {
// Do parents stuff first
super.auth()
// If parent failed, this code should not get executed anymore.
// Yes, here I could check if parent returned false and return false as well before
// continuing the next validation. Anyway I have to do this because grails, comprehendibly,
// will throw an exception if two redirects were executed in a row.
// (With this I just want to visualize the behaviour I'd expect)
if( someThingElseIsWrong() ) {
redirect( controller: "hello", action: "world")
return false
}
// After validation I can initialize the object
myGreatObject = new MyObject()
}
}
// A controller implementation
class MyDiagramController extends AbstractDiagramController {
// Overriden because of inidividual validation
#Override
protected initialize() {
// First do parent stuff
boolean succeeded = super.auth()
// Again, annoying double check
if( !succeeded ) {
return false
}
}
def myAction = {
myGreatObject.SpinAroundAndBeHappy()
}
}
Looks like it was a good idea to reduce the use-case to the minimum lines of code. Now it seem like Victor's suggestions (either canContinue or hasErrors) could solve this unpleasant circumstances somehow, even though it's some kind of workaround.
But somehow I don't like those double-checks. I'm still struggling against the fact, that all layers above the abstract base controller have to react on invalid validations that happened already before (and also should be managed by the base controllers on their own). From my point of view those checks should not be the business of the controller implementations.
PS: I hope no grave mistakes have slipped in the code.
As a workaround, you can return a boolean canContinue from an ancestor action or throw an exception, or check instance.hasErrors() in your case.
EDIT: The fact initialize() is called before an action looks like access control or another complete override of action semantics (before any part of action is executed). Please tell if my assumption is wrong.
When we did a custom security access to different actions, we annotated the actions with own tags like #SecuredDoodah (see #Secured), and added a Filter that completely overrides the action (for us, Filter responds with 403, but it's not necessary).
Filter might be better than beforeInterceptor. If you need to pass some state from Filter, like myGreatObject in the sample, you can inject a Service into Filter and save the state in the Service.
I'm sure there are better ways then my idea, but this should work transparently for Controllers.
You're limited by the fact that this is Java/Groovy and there's no way for a method call to immediately trigger an exit from a method (or Closure). I saw that another framework cheats and when you call render, redirect, etc. it throws an exception that's caught it the framework base class. This acts like a Goto, which doesn't really exist.
It's an expensive approach though - filling in all those stack frames unnecessarily is wasteful since it's not an exception case and the stack will always be ignored.
Unfortunately you need an approach like Victor's where you use boolean return values.

Singletons and ASP.NET MVC

Right now I'm having an issue with a Singleton that I just wrote for use in ASP.NET MVC -- My Singleton looks like this:
public sealed class RequestGenerator : IRequestGenerator
{
// Singleton pattern
private RequestGenerator()
{
requestList = new Stack<Request>();
appSettings = new WebAppSettings();
}
private static volatile RequestGenerator instance = new RequestGenerator();
private static Stack<Request> requestList = new Stack<Request>();
// abstraction layer for accessing web.config
private static IAppSettings appSettings = new WebAppSettings();
// used for "lock"-ing to prevent race conditions
private static object syncRoot = new object();
// public accessor for singleton
public static IRequestGenerator Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new RequestGenerator();
}
}
}
return instance;
}
}
private const string REQUESTID = "RequestID";
// Find functions
private Request FindRequest(string component, string requestId)
private List<Request> FindAllRequests(string component, string requestId)
#region Public Methods required by Interface
// Gets and increments last Request ID from Web.Config, creates new Request, and returns RequestID
public string GetID(string component, string userId)
// Changes state of Request to "submitted"
public void SetID(string component, string requestId)
// Changes state of Request to "success" or "failure" and records result for later output
public void CloseID(string component, string requestId, bool success, string result)
// Verifies that Component has generated a Request of this ID
public bool VerifyID(string component, string requestId)
// Verifies that Component has generated a Request of this ID and is owned by specified UserId
public bool VerifyID(string component, string userId, string requestId)
// Returns State of Request ID (Open, Submitted, etc.)
public Status GetState(string component, string requestId)
// Returns Result String of Success or Failure.
public string GetResult(string component, string requestId)
#endregion
}
And my controller code looks like this:
public ViewResult SomeAction()
{
private IRequestGenerator reqGen = RequestGenerator.Instance;
string requestId = reqGen.GetID(someComponentName, someUserId);
return View(requestId);
}
Everything works okay the first time I hit the controller. "reqGen" is assigned the instance of the Singleton. A new instance of Request is added to the internal list of the Singleton. And then we return a View(). The next time I hit this controller's SomeAction(), I'm expecting the Singleton to contain the List with the instance of SomeClass that I had just added, but instead the List is empty.
What's happened? Has Garbage Collection gobbled up my object? Is there something special I need to consider when implementing the Singleton pattern in ASP.NET MVC?
Thanks!
EDIT: Ahh, the lightbulb just went on. So each new page request takes place in a completely new process! Got it. (my background is in desktop application development, so this is a different paradigm for me...)
EDIT2: Sure, here's some more clarification. My application needed a request number system where something being requested needed a unique ID, but I had no DB available. But it had to be available to every user to log the state of each request. I also realized that it could double as a way to regulate the session, say, if a use double-clicked the request button. A singleton seemed like the way to go, but realizing that each request is in its own process basically eliminates the singleton. And I guess that also eliminates the static class, right?
EDIT3: ok, I've added the actual code that I'm working with (minus the implementation of each Method, for simplicity sake...) I hope this is clearer.
EDIT4: I'm awarding the green check mark to Chris as I'm beginning to realize that an application-level singleton is just like having a Global (and global's are evil, right?) -- All kidding aside, the best option really is to have a DB and SQLite seems like the best fit for now, although I can definitely see myself moving to an Oracle instance in the future. Unfortunately, the best option then would be to use an ORM, but that's another learning curve to climb. bugger.
EDIT5: Last edit, I swear. :-)
So I tried using HttpRuntime.Cache, but was surprised to find that my cache was getting flushed/invalidated constantly and couldn't figure out what was going on. Well, I was getting tripped up by a side-effect of something else I was doing: Writing to "Web.config"
The Answer --> Unbeknownst to me, when "web.config" is altered in anyway, the application is RESTARTED! Yup, everything gets thrown away. My singleton, my cache, everything. Gah. No wonder nothing was working right. Looks like writing back to web.config is generally bad practice which I shall now eschew.
Thanks again to everyone who helped me out with this quandary.
The singleton is specific to the processing instance. A new instance is being generated for each page request. Page requests are generally considered stateless so data from one doesn't just stick around for another.
In order to get this to work at the application level, the instance variable will have to be declared there. See this question for a hint on how to create an application level variable. Note that this would make it available across all requests.. which isn't always what you want.
Of course, if you are trying to implement some type of session state then you might just use session or use some type of caching procedure.
UPDATE
Based on your edits: A static class should not maintain data. It's purpose is to simply group some common methods together, but it shouldn't store data between method calls. A singleton is an altogether different thing in that it is a class that you only want one object to be created for the request.
Neither of those seem to be what you want.
Now, having an application level singleton would be available to the entire application, but that crosses requests and would have to be coded accordingly.
It almost sounds like you are trying to build an in memory data store. You could go down the path of utilizing one of the various caching mechanisms like .NET Page.Cache, MemCache, or Enterprise Library's Caching Application Block.
However, all of those have the problem of getting cleared in the event the worker process hosting the application gets recycled.. Which can happen at the worst times.. And will happen based on random things like memory usage, some timer expired, a certain number of page recompiles, etc.
Instead, I'd highly recommend using some type of persisted storage. Whether that be just xml files that you read/write from or embedding something like SQL Lite into the application. SQL Lite is a very lightweight database that doesn't require installation on the server; you just need the assemblies.
You can use Dependency Injection to control the life of the class. Here's the line you could add in your web.config if you were using Castle Windsor.
<component id="MySingleton" service="IMySingleton, MyInterfaceAssembly"
type="MySingleton, MyImplementationAssembly" lifestyle="Singleton" />
Of course, the topic of wiring up your application to use DI is beyond my answer, but either you're using it and this answer helps you or you can take a peak at the concept and fall in love with it. :)

Resources