Add a prefix to a bunch of urls - scala

I have a bunch of routes with the same prefix:
# with prefixes
GET /api/v1.0/action1 controllers.Api.action1
GET /api/v1.0/action2 controllers.Api.action2
GET /api/v1.0/action3 controllers.Api.action3
GET /api/v1.0/action4 controllers.Api.action4
# normal urls
GET /action1 controllers.Home.action1
GET /action2 controllers.Home.action2
I want to get rid of repetition of /api/v1.0/. The urls must remain the same, I just want to not write them manually for each url in route file. In Rails it's possible. If there any way to do that?

Either you implement your own router for these actions following James Ropers' post, as mentioned by Rich. Doing so, allows you add the following to your route file:
-> /api/v1.0 YourPathBindableController
Alternatively you can use a plugin, such as navigator, which offers you advanced routing. Your navigator route file would then contain something like:
// Namespace ...
namespace("api"){
namespace("v1"){
GET on "index" to Application.index _
}
}
// ... or with reverse routing support
val api = new Namespace("api"){
val v2 = new Namespace("v2"){
val about = GET on "about" to Application.about _
}
}

Related

How to run filter on demand scala play framework

I'm developing a scala application with play frame work, i have created a filter that filters every request coming from outside server,but now i'm stuck on how can i run a filter on demand since two days,i have 80 APIs 30 of them needs to run a specific filter, how can i read the request route template while the requests like this
GET /api/v1/:locale/:uuid core.controllers.MyClass.myAction1(locale: String)
GET /api/v1/:locale/:uuid/MyRoute core.controllers.MyClass.myAction2(locale: String)
GET /api/v1/:locale/:uuid/Foo core.controllers.MyClass.myAction3(locale: String)
GET /api/v1/:locale/orders/:orderId core.controllers.MyClass.myAction4(locale: String)
well, those routes are placed in routes file,
in filter i need to check weather if the route has :uuid variable or :orderId in order to run its specific filter, because both of their ids, i getting them as uuid so i couldn't expect the request, could i read the route template ?
You can access to some routing information from the RequestHeader#attrs:
// in your filter
val handlerDef: Option[HandlerDef] = request.attrs.get(Router.Attrs.HandlerDef)
See HandlerDef api
If you want to choose 30 out of 80 actions to run some common logic, you could also consider using "action builders" to provide that logic.
When you use Action { ... } you get a vanilla action. You can also make your own MyAction { ... } that wraps a normal Action and runs custom logic. This is an ActionBuilder. If you use this approach you just need to update your 30 actions to use that custom action builder.
See: https://www.playframework.com/documentation/2.6.x/ScalaActionsComposition#Custom-action-builders

RESTFUL URLS in rails?

Hi I'm building REST api for an app, I have a requirement in URL
such that url should be something like this e.g
www.abc.com/api/param1/value1/param2/value2/param3/value3.... and so on
There are cases
case: The number of params are not limited it can change frequent
if today it is something like this
www.abc.com/api/param1/value1/param2/value2/param3/value3
tomorrow it can be like this
www.abc.com/api/param1/value1/param2/value2/param3/value3/param4/value4
Is there a configuration where once you configure the url pattern
and every thing go smooth
and in conrtoller params should contain this kind of key-value pair
{ "param1" => "value1","param2" => "value2","param3" => "value3"...and so on }
any suggestion !! how to achieve this ??
If your params are not fixed you can use wildcard in routing
for e.g
get 'items/list/*specs', controller: 'items', action: 'list'
def list
specs = params[:specs] # e.g, "base/books/fiction/dickens" #split it and place in a hash
end
Rails routing provides a way to specify fully custom routes with static and dynamic segments as explained in the Rails Routing Guide.
Your requirement should be achievable with
get '/api/param1/:param1/param2/:param2/...', to: 'controller#action'
You can use route scoping for this particular kind of problem . In other way it is nested routes
More details : http://guides.rubyonrails.org/routing.html#nested-resources
This is a example,
GET /magazines/:magazine_id/ads/:id/edit ads#edit
return an HTML form for editing an ad belonging to a specific magazine
I think this would be helpful for you.

Parameter based redirect in nginx

I have http requests such as the one below being sent to an nginx server:
GET /app/handler?id=1234&param1=cbd&param2=234
Now, I want to rewrite the request to a different handler depending on the id param in the request. eg. redirect to handler_even for even ids and handler_odd for odd ids. This is shown below:
GET /app/handler?id=1234&param1=cbd&param2=234 => /app/handler_even?id=1234&param1=cbd&param2=234
GET /app/handler?id=123&param1=cbd&param2=234 => /app/handler_odd?id=123&param1=cbd&param2=234
I can do the rewrite using proxy_pass, but I'm unsure how to redirect using the id parameter value. Any idea how I could go about this? Would using "if" be the best way to go about this?
Any pointers would be useful
Rather than use an if directive, you could use a map. To internally rewrite the URI use:
map $arg_id $handler {
default /app/handler_even;
~[13579]$ /app/handler_odd;
}
server {
...
location = /app/handler {
rewrite ^ $handler last;
}
...
}
The map should be located at the same level as your server directive (as shown above), i.e. within the http container.
See this document for details.

playframework wildcard matching

Say I have the following url:
/baseurl
I'd like play to match and route on this url. I'd like to satisfy all these patterns:
/baseurl
/baseurl/
/baseurl/*
/baseurl/*/*
So basically I don't care what comes after '/baseurl'. I don't want to explicitly have to pass a variable to my action for the part coming in after '/baseurl' because I don't care about it: I just want it all routed to the same controller (for a single page app). I also am ok if I have to do this with multiple route lines.
I'd put something like this pretty high in the routes file:
GET /baseurl/*path/ controllers.Application.untrail(path: String)
(and the variations thereof)
And then in controllers.Application:
def untrail(path: String) = Action {
MovedPermanently("/baseurl")
}

How would I configure the global.config to allow for root path to actionMethod in MVC2?

specifically, the default directory naming structure is [Controller]/[ActionMethod] resulting in a rendered url like www.mysite.com/home/actionMethodName.
What if I want to simply imply the Controller (in this example, 'home') so that I can get a url that looks like this: www.mysite.com/actionMethodName.
I haven't seen many requests for this kind of configuration. I can see how it breaks convention, but I would imagine that there are lots of people who need root pathing.
Because you are planning to remove the {controller} element of the url, you may need to get a bit more specific with your other urls, e.g.:
routes.MapRoute("MyOtherControllerRoute", "Account/{action}", new { controller = "Account", action = "Index" });
routes.MapRoute("MyDefaultRoute", "{action}", new { controller = "Home", action = "Index" });
When the route table is interrogated, if the url such as www.mysite.com/Account is used, it will match the first route, because we have been specific about the pattern used to match the url. If we then do something like www.mysite.com/DoSomething it will use the default route we've selected last, trying to invoke the DoSomething action on the HomeController type.
Something which I've noticed is that a lot of MVC developers seems to assume that the url is strictly {something}/{something}/{something}, whereas it can essentially be anything you like, e.g, I can have a route that does: www.mysite.com/my-weird-and-wonderful-url which I could map specifically:
routes.MapRoute("Somewhere", "my-weird-and-wonderful-url", new { controller = "Whatever", action = "Whenever" });
Hope that helps.
Easy as apple pie - you just specify a route of your own! =)
An example:
routes.MapRoute(
"RootPathing",
"{action}",
new { controller = "Default", action = "Index" });
This will register a route that catches all paths, and try to map them to the DefaultController with an action name corresponding to the path. However, note that if you place this route above the included default route, you will not be able to reach any other controller than the DefaultController - hence, place this route below the default route in the chain. It will then be matched by all paths that don't match a controller name.
When debugging routes, Phil Haack's Routing Debugger is really worth taking a look at.