Add link to Spring Data REST Repository resource - spring-mvc

I want to create a Link to a resource within a Spring Data REST Repository. I know that we can use ControllerLinkBuilder.linkTo method to create links to MVC controllers. As far is I understand Spring Data REST creates MVC controllers out of our Repository interfaces. But if I use
Instance createdInstance = instanceRepository.save(instance);
Link link = linkTo(InstanceRepository.class).slash(createdInstance.getId()).withSelfRel();
to create the link, I just get http://localhost:8080/2 (without the Repository path). Nothing changes if I specify the path explicitly with the #RepositoryRestResource at the Repository.
Of course I could just create the link explicitly, but I don't want to repeat myself.
public interface InstanceRepository extends CrudRepository<Instance, Long> {
}
Any advice on what I could do to resolve this issue without having to violate DRY principles?

Searching through the Spring Data REST source code I found the class RepositoryEntityLinks, which is used within the framework. It has a pretty nasty constructor, but (at least in my project) I am able to #Autowire the class.
In short the following code does the trick. Nevertheless I would be pleased to hear another persons more educated opinion on this!
Link link = entityLinks.linkToSingleResource(InstanceRepository.class, 1L);

If anyone is confused on how to piece it all together, you need to inject RepsitoryEntityLinks into your controller like so. Note no AutoWired is needed since spring will automatically inject the values if theres just the 1 constructor.
entityLinks.linkToCollectionResource(TodoRepository.class) is saying to spring - "give me the link to the TodoRepositories collection endpoint which would be something like localhost:8080/api/todos"
#RestController
#RequestMapping(value="/api")
public class PriorityController {
private RepositoryEntityLinks entityLinks;
public PriorityController(RepositoryEntityLinks entityLinks) {
this.entityLinks = entityLinks;
}
#GetMapping(value = "/priorities", produces = MediaTypes.HAL_JSON_VALUE)
public ResponseEntity<Resources<Priority>> getPriorities() {
Link link = entityLinks.linkToCollectionResource(TodoRepository.class);
resources.add(link);
return ResponseEntity.ok(resources);
}
}

Related

ASP.Net MVC 6: Recursive Dependency Injection

Still exploring the new ASP.NET MVC5, now with build in DI!
No Problem so far, I can just inject my Handlers (I don't like the Term Service, since this defines to me a Platform-Neutral Interface):
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry(Configuration);
services.Configure<Model.Meta.AppSettings>(Configuration.GetSection("AppSettings"));
services.AddSingleton(typeof(Logic.UserEndPointConfigurationHandler));
services.AddSingleton(typeof(Logic.NetworkHandler));
services.AddMvc();
}
Works fine, also the strongly typed Configuration-Object "AppSettings" works perfectly fine.
Also the Injection in the Controllers works as well.
But now my collaps: I seperated my DataAccess from the Handlers, and obviously I'd like to inject them as well:
public class UserEndPointConfigurationHandler
{
private readonly DataAccess.UserEndPointAccess _access;
public UserEndPointConfigurationHandler(DataAccess.UserEndPointAccess access)
{
_access = access;
}
But bam, UserEndPointAccess can't be resolved. So it seems like even I directly request to DI an Class with a Parameterless-Constructor, I need to register that. For this case, sure I should Interface and register them, but what does that mean for internal helper classes I also inject?
According to the Docs: http://docs.asp.net/en/latest/fundamentals/dependency-injection.html#recommendations and also the examples I found, all people in the world only seem to communicate between Controllers and some Repositories. No Business-Layer and no Classes on different Abstraction-Levels in Assemblies.
Is the Microsoft DI approach something totally differnt than the good ol' Unity one, where I can really decouple as fine granular as I'd like to?
Thanks in advance.
Matthias
Edit #Nightowl: I add my answer here, since it's a bit longer.
First of all, Unity does automatically create Instances, if I request a conecrete Type. This allows me to inject Types I register and Types, like Helper classes etc. I don't need to. This combination allows me to use DI everywhere.
Also in your Example I'd need to know the DataAcces in the WebGui, which is quite thight coupled. Well, I know there are solutions for this via Reflection, but I hoped Microsoft did something in this Topic, but probably that'd mean to big of a change.
Also allows Unity to store Instances or Instructions how to create them, another huge feature, which is missing at the moment.
Probably I'm just to spoiled, what refined DI-Libraries do, probably they also do to much, but at the moment the Microsoft-Implementation is just a huge downgrade according to my Information.
MVC Core follows the the composition root pattern, which is where object graphs are created based off of a set of instructions to instantiate them. I think you are misinterpreting what the IServiceCollection is for. It does not store instances, it stores instructions on how to create instances. The instances aren't actually created until a constructor somewhere in the object graph requests one as a constructor parameter.
So, in short the reason why your service (which you call UserEndPointAccess) is not being instantiated when you request it is because you have not configured the IServiceCollection with instructions on how to create it.
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry(Configuration);
services.Configure<Model.Meta.AppSettings>(Configuration.GetSection("AppSettings"));
services.AddSingleton(typeof(Logic.UserEndPointConfigurationHandler));
services.AddSingleton(typeof(Logic.NetworkHandler));
// Need a way to instantiate UserEndPointAccess via DI.
services.AddSingleton(typeof(DataAccess.UserEndPointAccess));
services.AddMvc();
}
So it seems like even I directly request to DI an Class with a Parameterless-Constructor, I need to register that.
If you are doing DI correctly, each service class will only have a single constructor. If you have more than one it is known as the bastard injection anti-pattern, which essentially means you are tightly coupling your class definition to other classes by adding references to them as foreign defaults.
And yes, you need to register every type you require (that is not part of MVC's default registration). It is like that in Unity as well.

asp.net MVC 4 with Data Access Layer using Entity Framework 5?

In my project, i have first created my Data Access Layer using Entity Framework with the following projects in a single solution,
1.Domain Model - Entity Model (.edmx)
2.Services - Business Services, Dtos, Infrastructure(Configurator), Interfaces and Models(Repository)
Now the problem is, i want to connect this data access layer to my MVC project, i do not know how to make the data access layer projects to behave as the models for my mvc project. So can anyone tell me how to connect my data access layer into my controllers and views.. any references is appreciated. Thanks in Advance !
I think what you're asking is what's the best way for controllers to interact with your services and data layer?
One option is to use the mediator pattern, and decouple the services from the controllers.
There's a great implementation for ASP.NET MVC apps: ShortBus, also available on nuget that I've used in a number of projects, and so far it's worked great.
One of the nice things about ShortBus is it's support for dependency injection. In the example below, all the services are created with Ninject, and require the appropriate registration.
The basic idea is you define queries and commands that the controllers will use, and then add handlers to perform the actual work.
public class AddUser : ICommand<User>
{
public string Email { get; set; }
}
and then a handler:
public class AddUserHandler : ICommandHandler<AddUser, User>
{
private IDatabaseService _database;
private IEmailService _email;
public AddUserHandler(IDatabaseService database, IEmailService email)
{
_database = database;
_email = email;
}
public User Handle(AddUser command)
{
bool created = _database.CreateUser(command.Email);
if (created)
{
_email.SendWelcome(command.Email);
}
}
}
Then inside your controller, all you'd do is issue the command:
public class UsersController : Controller
{
private IMediator _mediator;
public UsersController(IMediator mediator)
{
_mediator = mediator;
}
public ActionResult Create(string email)
{
User user = _mediator.Send(new AddUser("foo#bar.com"));
}
}
The things I like about this pattern are:
Controllers don't need to know how to create a user. It issues a command, and the appropriate business logic handles it.
Each handler can require the services it needs. There's no need to pollute the controllers with services only used by a single action.
It's really easy to unit test. I use a mock, and only need to verify that _mediator.Send() was called with the correct parameters. Then to test the handler, I mock IDatabaseService and IEmailService and verify they are called correctly in the 2 cases.
Commands and queries can be reused, and again, the caller never needs to know what's required to handle the request.
As for the Views, I'd recommend ViewModels.
Each View gets it's own ViewModel, which holds whatever is required for showing that particular page. You'd then map your domain objects to their own individual ViewModels, possibly with AutoMapper.
What's nice about ViewModels is you can format the data appropriately (formatting a DateTime maybe), and then your Views don't need any special logic. If later you decide to update the DateTime format, you only need to change it in one place.
Create a (shared) interface to pass to the layer that's between the DAL and MVC, especially if you're unit testing. Use a repository pattern. Check it out here:
http://csharppulse.blogspot.com/2013/09/learning-mvc-part-5repository-pattern.html
This should get you going...

Groovy mixin on Spring-MVC controller

I'm trying to use Groovy mixin transformation on a spring-mvc controller class but Spring does not pickup the request mapping from the mixed in class.
class Reporter {
#RequestMapping("report")
public String doReport() {
"report"
}
}
#Mixin(Reporter)
#Controller
#RequestMapping("/a")
class AController {
#RequestMapping("b")
public String doB() {
"b"
}
}
When this code is run .../a/b url is mapped and works but .../a/report is not mapped and returns HTTP 404. In debug mode, I can access doReport method on AController by duck typing.
This type of request mapping inheritance actually works with Java classes when extends is used; so why it does not work with Groovy's mixin? I'm guessing it's either that mixin transformation does not transfer annotations on the method or that spring's component scanner works before the mixin is processed. Either way, is there a groovier way to achieve this functionality (I don't want AController to extend Reporter for other reasons, so that's not an option) ?
You can find below the responses I got from Guillaume Laforge (Groovy project manager) in Groovy users mailing list.
Hi,
I haven't looked at Spring MVC's implementation, but I suspect that
it's using reflection to find the available methods. And "mixin"
adding methods dynamically, it's not something that's visible through
reflection.
We've had problems with #Mixin over the years, and it's implementation
is far from ideal and bug-ridden despite our efforts to fix it. It's
likely we're going to deprecate it soon, and introduce something like
static mixins or traits, which would then add methods "for real" in
the class, which means such methods like doReport() would be seen by a
framework like Spring MVC.
There are a couple initiatives in that area already, like a prototype
branch from Cédric and also something in Grails which does essentially
that (ie. adding "real" methods through an AST transformation).
Although no firm decision has been made there, it's something we'd
like to investigate and provide soon.
Now back to your question, perhaps you could investigate using
#Delegate? You'd add an #Delegate Reporter reporter property in your
controller class. I don't remember if #Delegate carries the
annotation, I haven't double checked, but if it does, that might be a
good solution for you in the short term.
Guillaume
Using the #Delegate transformation did not work on its own, so I needed another suggestion.
One more try... I recalled us speaking about carrying annotations for
delegated methods... and we actually did implement that already. It's
not on by default, so you have to activate it with a parameter for the
#Delegate annotation:
http://groovy.codehaus.org/gapi/groovy/lang/Delegate.html#methodAnnotations
Could you please try with #Delegate(methodAnnotations = true) ?
And the actual solution is:
class Reporter {
#RequestMapping("report")
public String doReport() {
"report"
}
}
#Controller
#RequestMapping("/a")
class AController {
#Delegate(methodAnnotations = true) private Reporter = new Reporter
#RequestMapping("b")
public String doB() {
"b"
}
}
When you map requests with annotations, what happens is that once the container is started, it scans the classpath, looks for annotated classes and methods, and builds the map internally, instead of you manually writing the deployment descriptor.
The scanner reads methods and annotations from the compiled .class files. Maybe Groovy mixins are implemented in such a way that they are resolved at runtime, so the scanner software can't find them in the compiled bytecode.
To solve this problem, you have to find a way to statically mixin code at compile time, so that the annotated method is actually written to the class file.

Clarity about helpers in MVC3?

Are helpers in MVC3 used in the controller as well as the views?
Is a helper the right place to put commonly used controller methods?
I want to create a common method to get all sub children IDs in a database and make sure it is in the right area. I just want to make sure I am putting my logic in the right area.
Thanks
You could implement a base Controller for that logic. Helpers, or extension methods, are good for when you don't want to change the interface for something.
The HtmlHelper is not available to the controller, because the controller should not be responsible for generating HTML, but the UrlHelper is available within the controller.
A method to get specific data from your database does not belong in your controller, or in a UrlHelper or an HtmlHelper. You should create a separate class for this logic, and then call the method on this class from within your controller. If you are using Dependency Injection, which I suggest, your controller code might look like this:
public class MyController
{
IMyDataUtil _dataUtil;
public MyController(IMyDataUtil dataUtil)
{
_dataUtil = dataUtil;
}
public ActionResult SomeAction(int parentId)
{
var childIds = _dataUtil.GetChildIds(parentId);
...
}
}
As you can see, this allows you to keep the data-access code in a class specifically designed for that purpose. The fact that this controller depends on that utility class is immediately obvious, and doesn't take that much more code than calling an extension method on a helper. Controllers that don't deal with that class's methods won't need to have it available.
On the other hand, if there are methods that are likely to be used by a bunch of different controllers, injecting this same data class into all of them may become cumbersome. In that case, you could:
Extend a base class that has an instance of the data-access class injected into it via method or property injection, and which then exposes it to sub-classes via a protected or public property, or
Create your own helper class that wraps the classes and methods you're likely to use in all your controllers, and inject that class so you only have one dependency for a variety of common functions, or
Combine steps 1 and 2.
If by "helpers" you're referring to things such as HtmlHelper then, no, these aren't used by the controller as in theory you could take your controllers and re-use them with an entirely different rendering engine (for example WPF) as the controller isn't responsible for rendering.
If you're talking about, as I think you are, helper classes/methods that manipulate your data ready for it to be put into a Model by a Controller and then handed off to a View for presentation, then you could consider a "business logic" layer. For example, if you were talking about (the ever typical) Bank Account example, you could have a:
public class BankAccountService
{
public IEnumerable<string> GetAllAccountIdsForCustomer(int customerId)
{
// Talk to the database here and retrieve the account id's for a customer
}
public string GetCustomerName(int customerId)
{
// Talk to the database here and retrieve the customer's name
}
}
Your controller would then:
public ActionResult AccountNumbers(int customerId)
{
var model = new AccountNumbersModel();
model.CustomerId = customerId;
model.AccountNumbers = BankAccountService.GetAllAccountIdsForCustomer(customerId);
return View(model);
}
Obviously in this example you'd need to have a class called AccountNumbersModel defined and you'd also probably want to consider using Dependency Injection to provide an instance of BankAccountService to your controller, but describing how to go about all that is kinda outside the scope of this answer.
The advantages this approach gives you are testability and separation, each piece of code is responsible for one task, and you reduce the complexity of each individual piece and make it easier to make changes without breaking things.
I want to create a common method to get all sub children IDs in a database and make sure it is in the right area. I just want to make sure I am putting my logic in the right area.
That sounds like a job for an ActionFilter.

Asp.net MVC RouteBase and IoC

I am creating a custom route by subclassing RouteBase. I have a dependency in there that I'd like to wire up with IoC. The method GetRouteData just takes HttpContext, but I want to add in my unit of work as well....somehow.
I am using StructureMap, but info on how you would do this with any IoC framework would be helpful.
Well, here is our solution. Many little details may be omitted but overall idea is here. This answer may be a kind of offtop to original question but it describes the general solution to the problem.
I'll try to explain the part that is responsible for plain custom HTML-pages that are created by users at runtime and therefore can't have their own Controller/Action. So the routes should be either somehow built at runtime or be "catch-all" with custom IRouteConstraint.
First of all, lets state some facts and requirements.
We have some data and some metadata about our pages stored in DB;
We don't want to generate a (hypothetically) whole million of routes for all of existing pages beforehand (i.e. on Application startup) because something can change during application and we don't want to tackle with pushing the changes to global RouteCollection;
So we do it this way:
1. PageController
Yes, special controller that is responsible for all our content pages. And there is the only action that is Display(int id) (actually we have a special ViewModel as param but I used an int id for simplicity.
The page with all its data is resolved by ID inside that Display() method. The method itself returns either ViewResult (strongly typed after PageViewModel) or NotFoundResult in case when page is not found.
2. Custom IRouteConstraint
We have to somewhere define if the URL user actually requested refers to one of our custom pages. For this we have a special IsPageConstraint that implements IRouteConstraint interface. In the Match() method of our constraint we just call our PageRepository to check whether there is a page that match our requested URL. We have our PageRepository injected by StructureMap. If we find the page then we add that "id" parameter (with the value) to the RouteData dictionary and it is automatically bound to PageController.Display(int id) by DefaultModelBinder.
But we need a RouteData parameter to check. Where we get that? Here comes...
3. Route mapping with "catch-all" parameter
Important note: this route is defined in the very end of route mappings list because it is very general, not specific. We check all our explicitly defined routes first and then check for a Page (that is easily changeable if needed).
We simply map our route like this:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
Stop! What is that DependencyRouteConstraint thing appeared in mapping? Well, thats what does the trick.
4. DependencyRouteConstraint<TConstraint> class
This is just another generic implementation of IRouteConstraint which takes the "real" IRouteConstraint (IsPageConstraint) and resolves it (the given TConstraint) only when Match() method called. It uses dependency injection so our IsPageConstraint instance has all actual dependencies injected!
Our DependencyRouteConstraint then just calls the dependentConstraint.Match() providing all the parameters thus just delegating actual "matching" to the "real" IRouteConstraint.
Note: this class actually has the dependency on ServiceLocator.
Summary
That way we have:
Our Route clear and clean;
The only class that has a dependency on Service Locator is DependencyRouteConstraint;
Any custom IRouteConstraint uses dependency injection whenever needed;
???
PROFIT!
Hope this helps.
So, the problem is:
Route must be defined beforehand, during Application startup
Route's responsibility is to map the incoming URL pattern to the right Controller/Action to perform some task on request. And visa versa - to generate links using that mapping data. Period. Everything else is "Single Responsibility Principle" violation which actually led to your problem.
But UoW dependencies (like NHibernate ISession, or EF ObjectContext) must be resolved at runtime.
And that is why I don't see the children of RouteBase class as a good place for some DB work dependency. It makes everything closely coupled and non-scalable. It is actually impossible to perform Dependency Injection.
From now (I guess there is some kind of already working system) you actually have just one more or less viable option that is:
To use Service Locator pattern: resolve your UoW instance right inside the GetRouteData method (use CommonServiceLocator backed by StructureMap IContainer). That is simple but not really nice thing because this way you get the dependency on static Service Locator itself in your Route.
With CSL you have to just call inside GetRouteData:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
or with just StructureMap (without CSL facade):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
and you're done. Quick and dirty. And the keyword is "dirty" actually :)
Sure, there is much more flexible solution but it needs a few architectural changes. If you provide more details on exactly what data you get in your routes I can try to explain how we solved our Pages routing problem (using DI and custom IRouteConstraint).

Resources