rOrlig
rOrlig

Reputation: 2529

Playframework routes with different query parameters

I have two methods in my search controller

searchBoundingBox - does bounding box search and requires the bounding box latitude and longitude values. search - does distance search (does distance based search from the center point).

I have defined my two routes in route file as below.

#Search
#bounding box
GET     /search                             controllers.Search.searchBoundingBox(swLatitude:java.lang.String,swLongitude:java.lang.String, neLatitude:java.lang.String,neLongitude:java.lang.String)

# distance based
GET     /search                             controllers.Search.search(latitude:java.lang.String,longitude:java.lang.String, offset:java.lang.Integer?=0,distance:java.lang.Integer?=50, limit:java.lang.Integer?=10)

But when I create a query in the 2nd route (distance based) it is not resolved.

Any workarounds !!!( Note if I change the order of the routes then the bounding box searches fails)

Upvotes: 4

Views: 4909

Answers (2)

Schleichardt
Schleichardt

Reputation: 7542

If you are forced to use query params you can use one action for both searches as a workaround:

GET     /search   controllers.Search.search

and fetch the query parameters yourself:

Scala:

def search = Action { request =>
     val latitude = request.queryString.getOrElse("latitude", Seq()).headOption.getOrElse("default")

Java:

public static Result search() {
        String latitude = request().queryString().get("latitude")[0];//of course check if param is in map

So you can split the action:

if(latitude != null)
   searchWithoutBoundingBox()
else
   searchBoundingBox()

You see this is not a nice and typesafe API so it's better to follow Julien's and biesior's approach.

Upvotes: 5

biesior
biesior

Reputation: 55798

That's normal when two routes uses the same method (GET) and same path (/search) only first is used, there's no derogation from this rule.

First solution given by Schleichardt is possible however for best safety you should strictly control types of inputs.

Second, much faster and much easier solution is... just paths of routes unique ie:

#bounding box
GET     /search/bound/:swLatitude/:swLongitude/:neLatitude/:neLongitude      controllers.Search.searchBoundingBox(swLatitude: String, swLongitude: String, neLatitude: String, neLongitude: String)

# distance based
GET     /search/distance/:latitude/:longitude   controllers.Search.search(latitude: String, longitude: String, offset: Int?=0, distance: Int?=50, limit: Int?=10)

Btw you don't need give full path to common types like String, Integer, etc. if your Java method uses an Integer type construct routes with Scala Int.

Upvotes: 3

Related Questions