Issue with Openrasta's Get methods' precedence in resource handler - methods

I am new to openRasta framework. I have a resource called Project.I have 2 different types of GET to be done on this resource as i need different info on these two GETs.My configuration is like this
ResourceSpace.Has.ResourcesOfType<IList<Project>>()
.AtUri("/projects")
.And.AtUri("/miniprojects")
.HandledBy<ProjectHandler>()
.AsJsonDataContract()
.And.AsXmlDataContract();
and my methods in Handler are as below
[HttpOperation(HttpMethod.GET, ForUriName = "/projects")]
public OperationResult GetProjectsList()
{
}
[HttpOperation(HttpMethod.GET, ForUriName = "/miniprojects")]
public OperationResult GetMiniProjectList()
{
}
Whenever i am doing some GET on this resource, whatever my URL is for example http://localhost/projects or http://localhost/miniprojects) the very first method with GetXXX name in handler class gets called every time. When I changed the sequence of the GetXXX methods in handler file the other method gets called.
So my question is, does sequence of methods in Handler determines which GetXXX method to be called? Moreover, I specified different "ForUriName" in the HttpOperation attribute for each GetXXX method as mentioned in the snippet, but still the sequence took the precedence.
Can any one help me in resolving this issue? Or let me know if I am missing anything.
Thanks in advance.

If threre is no way do make the distinction between two URIs then we don't guarantee any order at all.
If you really want to use URI routes in this way (as opposed to model different resources), then your uri needs to be registered with a name
.AtUri("/miniprojects").Named("miniprojects")
The Named bit needs to match the attribute
[HttpOperation(ForUriName="miniprojects")]

Related

How are request parameters mapped into RenderingModel of magnolia?

Im using Magnolia RenderingModel in combination with Freemarker.
I have URLs like the following:
http://anyPath/context?productTypes=XXXXX&productTypes=YYYYY
my rendering model class looks like:
class MyModel extends RenderingModelImpl {
...
private String[] productTypes;
...
}
However the mentioned array contains only the first value, but not the second.
I checked the behaviour of template directives like ctx.getParameters(). This shows the same behaviour, I get only the first value returned. But if im using ctx.getParameterValues(paramName), it returns both values.
This leads me to following questions:
How would I go, if I want to lookup how the request parameters are mapped into the rendering model, or better:
How can i change the behaviour of that ?
Can anyone acknowledge, that this behaviour is wrong ?
It used to be mentioned in documentation and I believe it still is - if you use .getParameters() you get only first value for multivalue parameter. If you want to get all the values, you need to use .getParameterValues(String param).
From what I understand reasons for that were backward compatibility.
As for changing the behavior, you would need to write your own renderer (e.g. by extending default FreemarkerRenderer and override info.magnolia.rendering.renderer.AbstractRenderer.newModel(Class<T>, Node, RenderableDefinition, RenderingModel<?>) method which instantiates and populates the model class.
Alternatively you can provide fix for above set population method and submit it to Magnolia as a patch. While the .getParameters() behavior is iirc on purpose, the model param population might not be, so you have high chance of getting that changed.

Manually calling controller method with parameter and still have method injection

How can I call a controller method manually specifying some input parameters yet still have method injection work for the parameters not specified (example below).
routes.php
$myController->index($id);
controllers/MyControllerOne.php
class MyControllerOne
{
public function index($id, MyRequest $request)
{
}
}
extra information
The reason I need this is because I have special information in my routes that determines which controller should be executed such as /myroute/{data}/{id}. It's a bit unorthodox but it's a necessary evil given the scope of our system.
Once I resolve within my routes which controller needs to be called I then want to call the method on that controller. $controllerInstance->index($id).
If it's only for Request, I think you could manually pass this $this->app->make('Request'), like so
$controllerIntance->index($id, $this->app->make('Request'))
Note that you actually don't have to inject Request, since you might as well use App::make inside of your controller. But I'm not sure how good this decision is in case of testability and coupling.
For more info:
This function resolves 'Request' out of the container, that is instantiates or returns an existing instance (depending of the type of service provider).
Using make is described here http://laravel.com/docs/5.0/container (see "Resolving"). I also found this answer helpful, to understanding how the container works https://stackoverflow.com/a/25798288/1627227

How to Pass a Route Parameter to a Property on my Controller with WebApi?

Suppose I have a route like the following:
/api/v1/{organisationId}/resource/{resourceId}
Since there are likely to be a number of different types of resources hanging off an organisation, I'd like a common way of dealing with the organisationId.
What I thought of doing is creating a base controller (inheriting from ApiController, obviously) which would have an OrganisationId property.
Is there any way to get WebApi to pass the organisationId route parameter to a property on the controller, rather than to a parameter on the action method?
How about this?
public int OrganisationId
{
get
{
return Convert.ToInt32(Request.GetRouteData().Values["organisationId"]);
}
}
This is not using the model binding layer and is assuming that organisationId would be present in the route data. It is simple and a bit less flexible than what web API model binding offers.
The downside to reading the route from within the property getter is unit testing could be a challenge. Another possible approach is to explore implementing your own IHttpControllerActivator that sets the OrganizationId property. Yes, for this to work, you will need a base controller or the property defined in the individual controllers, when not derived from the base. If you go with base, you can cast IHttpController type to the base and set the property. Or you can resort to reflection.

method name for a long method

The good style (Clean Code book) says that a method's name should describe what the method does. So for example if I have a method that verifies an address, stores it in a database, and sends an email, should the name be something such as verifyAddressAndStoreToDatabaseAndSendEmail(address);
or
verifyAddress_StoreToDatabase_SendEmail(address);
although I can divide that functionality in 3 methods, I'll still need a method to call these 3 methods. So a large method name is inevitable.
Having And named methods certainly describes what the method does, but IMO it's not very readable as names can be very very large. How would you solve it?
EDIT: Maybe I could use fluent style to decompose the method name such as:
verifyAddress(address).storeToDatabase().sendEmail();
but I need a way to ensure the order of invocation. Maybe by using the state pattern, but this causes the code to grow.
How I approach this is to make the 3 smaller methods as you mentioned and then in the higher method that calls the 3 smaller ones, I name it after the "why" I need to do those three things.
Try to define why you need to do those steps and use that as the basis of the method name.
A single method should not do 3 things. Thus divide the work into 3 methods:
verifyAddress
storeAddress
sendEmail
I'm following up on my previous comment, but I've got more here than would fit reasonably in a comment so I'm answering.
The details of the method belong in the documentation not in the name of the method (in my opinion). Think of it this way... By putting SendEmail in the name of the method, you're committing implementation details to the method name. What if a decision is made down the road to send notification via SMS or twitter or something else instead of email? Do you change the name of the method and break your API, or do you have a method name that misleads the consumers of the API? Something to consider.
If you insist on keeping the functionality of the method in its name, I'd urge you to find something more generic. Perhaps something along the lines of VerifySaveAndNotify(Address address). That way, the method name tells you what it's doing without specifying how it does it. The parameter of type Address let's you know what is being verified and saved. All of that works together to make your method name informative, flexible, and terse.
EDIT: Maybe I could use fluent style to decompose the method name such as:
verifyAddress(address).storeToDatabase().sendEmail();
but I need a way to ensure the order of invocation. Maybe by using the state pattern, but this causes the code to grow.
To ensure ordering of commands in a fluent style, each result would be an object that exposes only the functionality required by the next step. For example:
public class Verifier
{
public DataStorer VerifyAddress(string address)
{
...
return new DataStorer(address);
}
}
public class DataStorer
{
public Emailer StoreToDataBase()
{
...
return new Emailer(...);
}
}
public class Emailer
{
public void SendEmail()
{
...
}
}
This is handy if you need to create a very granular design and want to optimise your classes for reuseability, but is likely to be design overkill under most circumstances. Better probably as others have said to choose a name that represents what the whole process is supposed to represent. You could simply call it "StoreAndEmail", making an assumption that verification is something you do routinely before committing data to any destination. The alternative if you don't mind names being long is to simply describe it in full and accept that a long name is necessary. In the end, it really doesn't cost you anything, but can certainly make you code more specific in its intent.

Where to perform Parameter Validation within nested methods

Where is the proper place to perform validation given the following scenario/code below:
In MethodA only: since this is the public method which is meant to be used by external assemblies?
In MethodA and B since both these can be accessed outside the class?
Or Methods A, B and C since method C may be used by another internal method (but it might not efficient since the programmer can see the code for MethodC already and therefore should be able to know the valid parameters to pass)?
Thanks for any input.
public class A
{
public void MethodA(param)
{
MethodB(param);
}
internal void MethodB(param)
{
MethodC(param);
}
private void MethodC(param)
{
}
}
Parameter validation should always be performed regardless of the caller's location (inside or outside of the assembly). Defensive programming, one can say.
MethodC; that way the parameter always gets checked, even if someone comes along later and adds a call to MethodC from within class A, or they make MethodC public. Any exception should be bubbled up to where it can be best dealt with.
There isn't a 'proper' place, except to adhere to DRY principles and avoid copying the validation code to several places. I'd normally suggest that you delay validation to the latest possible stage, as then if the parameter is never used you don't need to spend time validating it though. This also gives the validation some locality to the place it is used, and you never need to think 'oh, has this parameter been validated yet?' as the validation is right there.
Given that a more likely senario would involve each method having different parameters and also probably some
if (P1 == 1) { MethodA(P2) } else { MethodB(P2) }
type logic in hte longer term it makes more sense to validate each parameter at the point of entry, escpecially as you may want different error handling depending on where hte method was called.
If the validation logic for a given parameter start to get complex ( i.e. more than five lines of code) then consider a private method to validate that parameter.

Resources