I have some custom Controllers that add additional endpoints and operations for a service that utilizes Spring Data REST for the base implementation. I've annotated the Controller with #BasePathAwareController to make sure that the controller plays nice with SDR.
What I basically want is to leverage all of the error handling, validation, etc that SDR is providing, and I've build the controller so it calls the ApplicationEventPublisher the same way that the SDR controllers do for the base implementation. One issue is that when validation fails, the response is a 500 status, and instead of a 400 with the details of the validation messages encoded in JSON as I would expect.
I tried using #RepositoryRestController instead of #BasePathAwareController, but that didn't matter. Is there a way to configure the SDR exception handling for my own controllers without copying the code and re-implementing all of the logic?
Related
I'd read it somewhere that whenever one needs to do data intensive work then Webapi could be used. Ex: autocomplete textbox where we get data from using ajax on key press.
Now someone told me that Webapi shouldn't be used within applications which are not externally accessed. Rather action should be used to the same work as it is capable of returning the data back in a similar fashion to webapi.
I'd like to know your suggestions over it.
Depends on how you look at it. If all you need is ajax-ification of your controller actions, then you really don't need Web-API. Your actions can return a JsonResult and it is very easy to consume that from your client side through an AJAX call.
Web-API makes it easy for you to expose you actions to external clients. It supports HTTP protocol and Json and XML payloads automatically, out of the box, without you writing the code for it. Now, there is nothing preventing you from consuming the same Web-API actions from your own internal clients in an AJAX manner.
So the answer to your question depends on your design. If you don't have external clients, then there is no string need for you to have Web-API. Your standard controller actions can do the job.
I would like to ask whether it's a good approach to redirect from within a model instead of a controller.
The reason I want to do that is because it is easier to unit test redirection from a model (I just pass a mock redirector object to the model in my tests) as opposed to controller which is more difficult to unit test. It also keeps controller thinner as all I do in the controller is create an instance of the model and pass it parameters from the request object. There is not a single if/else in the controller this way.
Is it a bad practise?
Most often in webapplications - MVC or not - redirects are implemented on a high-level layer. In non OOP code this often is a high level global function that knows a lot about the global static state and what represents a request and a response therein.
In more OOP driven sites, you find this often as a method with the "response" object (compare Symfony2 and HTTP Fundamentals; note that Symfony2 is not MVC), however, it often then has also some similar methods (e.g. see Difference between $this->render and $this->redirect Symfony2).
As most often those "response" objects are central in the web-application this qualifies as well as a high-level layer in my eyes.
From a testing standpoint - especially with integration testing - you normally do not need to test for redirects specifically. You should test that generally your redirect-functionality works on the HTTP layer so that parts of your application that make use of it can rely on it. Common problems are to not really follow the suggestions given in the HTTP/1.1 specs like providing a response body with redirects. A well working webapplication should honor that. Same for using fully qualified URIs.
So how does all fit this into MVC here? In a HTTP context this could be simplified as the following:
The response is to tell the user to go somewhere else.
If the user would not be important, the application could forward directly - that is executing a different command, the client would not be used for that, the redirect not necessary (sub-command).
The response is to say: Done. And then: See next here this command (in form of an URI).
This pretty much sounds like that the actual redirect is just some output you send to the client on the protocol level in client communication. It belongs into the interface of that protocol you want to support. So not into the model but into the client-interface and the boundary of the client interface inside an MVC application is the controller AFAIK.
So the redirect probably is a view-value-object with a special meaning. To get that working in a HTTP MVC you need a full URL abstraction which most PHP frameworks and libraries make a big round around because it's not well known how that works. So in the end I'd say: Do as Symfony2 has done, place it in a high level layer component, drop MVC and live with the deficiencies.
Everything else is hard to achieve, if you try otherwise, there is high risk to not stop with abstracting anymore.
Neither controller nor model should be redirecting anything anywhere. HTTP Location header is form of a response, which strictly in purview of views.
Model layer deals with business logic, it should be completely oblivious even to the existence of presentation layer.
Basically, it goes down to this: controllers handle input, views handle output. HTTP headers are part of output.
Note: when dealing with Rails clones, it is common to see redirects performed in "controller". It is because what they call "controller" is actually a merger of view and a controller responsibilities. This is a side-effect of opting to replace real views with simple templates as the 3rd side of triad.
I would say yes, it is wrong. As far as I understood, while models manage data and views manage layouts (i.e. how data should be displayed), controllers are only and exclusively in charge of the HTTP requests/responses management (in the case of a web app), and redirections typically belong to that tier in my opinion.
Examples in common frameworks
Symfony:
return $this->redirect($this->generateUrl('homepage'));
Spring MVC:
return "redirect:/appointments";
I think that you could have a model for your applications work flow or navigation (in your model layer) and then have your controller translate the different concepts in your work flow/navigation model into what views are to be displayed.
Your work flow class/module could know about the different activities/phases/steps that are available to the user, and it model your application kind of like a state machine. So your controller would make calls to this module to update the state and would recieve a response telling the controller which activity/phase/step it should go to.
That way your work flow model is easy to test but it still doesn't know about your view technology.
Many mentioned in comments these thoughts, so here is a summary:
The logic to figure out whether you need a redirect and what your redirect should be belongs into the controller. The model simply takes the data a view needs. This happens AFTER you decided which view to render. Think of the redirect as an instruction to perform a different controller action.
I use ASP.NET MVC and the controllers generate a RedirectResult for this purpose, which are completely unit testable. I don't know what is supported in your framework, but this is what MVC would do:
public class MyController : Controller {
public ActionResult ShowInfo(string id) {
if( id == null ) {
return new RedirectResult("searchpage");
} else {
return new ViewResult("displayInfo");
}
}
}
In your unit tests, you instantiate MyController and check the type of the result and optionally, the url or view name.
Whether your redirect is actually performed is not a unit test issue - that's essentially making sure your framework is working right. What you need to test is that you are giving the correct instruction (i.e. the redirect) and the correct url.
Long story as brief as possible...
I have an existing application that I'm trying to get ServiceStack into to create our new API. This app is currently an MVC3 app and uses the UnitOfWork pattern using Attribute Injection on MVC routes to create/finalize a transaction where the attribute is applied.
Trying to accomplish something similar using ServiceStack
This gist
shows the relevant ServiceStack configuration settings. What I am curious about is the global request/response filters -- these will create a new unit of work for each request and close it before sending the response to the client (there is a check in there so if an error occurs writing to the db, we return an appropriate response to the client, and not a false "success" message)
My questions are:
Is this a good idea or not, or is there a better way to do
this with ServiceStack.
In the MVC site we only create a new unit
of work on an action that will add/update/delete data - should we do
something similar here or is it fine to create a transaction only to retrieve data?
As mentioned in ServiceStack's IOC wiki the Funq IOC registers dependencies as a singleton by default. So to register it with RequestScope you need to specify it as done here:
container.RegisterAutoWiredAs<NHibernateUnitOfWork, IUnitOfWork()
.ReusedWithin(ReuseScope.Request);
Although this is not likely what you want as it registers as a singleton, i.e. the same instance returned for every request:
container.Register<ISession>((c) => {
var uow = (INHibernateUnitOfWork) c.Resolve<IUnitOfWork>();
return uow.Session;
});
You probably want to make this:
.ReusedWithin(ReuseScope.Request); //per request
.ReusedWithin(ReuseScope.None); //Executed each time its injected
Using a RequestScope also works for Global Request/Response filters which will get the same instance as used in the Service.
1) Whether you are using ServiceStack, MVC, WCF, Nancy, or any other web framework, the most common method to use is the session-per-request pattern. In web terms, this means creating a new unit of work in the beginning of the request and disposing of the unit of work at the end of the request. Almost all web frameworks have hooks for these events.
Resources:
https://stackoverflow.com/a/13206256/670028
https://stackoverflow.com/search?q=servicestack+session+per+request
2) You should always interact with NHibernate within a transaction.
Please see any of the following for an explanation of why:
http://ayende.com/blog/3775/nh-prof-alerts-use-of-implicit-transactions-is-discouraged
http://www.hibernatingrhinos.com/products/nhprof/learn/alert/DoNotUseImplicitTransactions
Note that when switching to using transactions with reads, be sure to make yourself aware of NULL behavior: http://www.zvolkov.com/clog/2009/07/09/why-nhibernate-updates-db-on-commit-of-read-only-transaction/#comments
I am developing an application that exposes a WCF service using the Message/Response pattern for service methods. The application is using Unity 2.0 for dependency injection and the Validation Application Block from MS Patterns & Practices. I've already gotten Unity tied into WCF using a custom HttpModule I picked up from several website a while back and everything works great.
In my service interface I have a method such as:
DoSomethingResponse DoSomething(DoSomethingRequest request)
I can easily attach VAB attributes to the service contract to verify that 'request' is never null but I also want to validate the contents of the request object.
To do this, I inject the validator into the DoSomethingRequest constructor and include an internally scoped IsValid property which handles interacting with the VAB validator. Unfortunately, this constructor doesn't get called because WCF deserializes the object and constructors aren't used.
Without getting into the merits of having the request object be a simple DTO versus having some server-side business logic, is there a way to cleanly inject dependencies into an object passed into WCF service as an argument?
If I'm understanding your issue correctly, you have properties on DoSomethingRequest that are instances of some other classes (data contracts) and you want to validate your data contracts as well? Is there some reason you can't just apply validation attributes to your data contract classes as well? This is the approach I've used when using WCF with VAB integration and it's worked out quite nicely.
So it turns out that adding the validation attributes to my DataContract actually works with no additional code. Unfortunately, it doesn't work if validation is defined in the app's config file (app.config or web.config).
As a result, I've stripped out the constructor injection and IsValid property on my DataContract (request object) which makes it more of an annotated DTO which I think is preferred anyway. I only wish that it would work the same with the XML configuration.
I am trying to solve a problem where i have a WCF system that i have built a custom Host, Factory host, instance providers and service behaviors to do authentication and dependency injection.
However I have come up with a problem at the authorisation level as I would like to do authorisation at the level of the method being called.
For example
[OperationContract]
[WebGet(UriTemplate = "/{ConstituentNumber}/")]
public Constituent GetConstituent(string ConstituentNumber)
{
Authorisation.Factory.Instance.IsAuthorised(MethodBase.GetCurrentMethod().Name, WebOperationContext.Current.IncomingRequest.Headers["Authorization"]);
return constituentSoapService.GetConstituentDetails(ConstituentNumber);
}
Basically I now have to copy the Call to IsAuthorised across every web method I have. This has two problems.
It is not very testable. I Have extracted the dependecies as best that I can. But this setup means that I have to mock out calls to the database and calls to the
WebOperationContext.
I Have to Copy that Method over and over again.
What I would like to know is, is there a spot in the WCF pipeline that enables me to know which method is about to be called. Execute the authorisation request. and then execute the method based on the true false value of the authorisation response.
Even better if i can build an attribute that will say how to evaluate the method.
One possible way to do what you want might be by intercepting requests with a custom IDispatchMessageInspector (or similar WCF extension point).
The trick there, however, is that all you get is the raw message, but not where it will be processed (i.e. the method name). With a bit of work, however, it should be possible to build a map of URIs/actions and the matching method names (this is how you'd do it for SOAP, though haven't tried it for WebGet/WebInvoke yet).