How to access Scalatra web service GET parameters

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is a short recipe, Recipe 15.7, “How to access Scalatra web service GET parameters.”

Problem

When creating a Scalatra web service, you want to be able to handle parameters that are passed into a method using a GET request.

Solution

If you want to let parameters be passed into your Scalatra servlet with a URI that uses traditional ? and & characters to separate data elements, like this:

http://localhost:8080/saveName?fname=Alvin&lname=Alexander

you can access them through the implicit params variable in a get method:

/**
  * The URL
  * http://localhost:8080/saveName?fname=Alvin&lname=Alexander
  * prints: Some(Alvin), Some(Alexander)
  */
get("/saveName") {
    val firstName = params.get("fname")
    val lastName = params.get("lname")
    <p>{firstName}, {lastName}</p>
}

However, Scalatra also lets you use a “named parameters” approach, which can be more convenient, and also documents the parameters your method expects to receive. Using this approach, callers can access a URL like this:

http://localhost:8080/hello/Alvin/Alexander

You can handle these parameters in a get method like this:

get("/hello/:fname/:lname") {
    <p>Hello, {params("fname")}, {params("lname")}</p>
}

As mentioned, a benefit of this approach is that the method signature documents the expected parameters.

With this approach, you can use wildcard characters for other needs, such as when a client needs to pass in a filename path, where you won’t know the depth of the path beforehand:

get("/getFilename/*.*") {
    val data = multiParams("splat")
    <p>{data.mkString("[", ", ", "]")}</p>
}

You can understand this method by looking at a specific example. Imagine a GET request to the http://localhost:8080/getFilename/Users/Al/tmp/file.txt URL. The comments in the following code show how this URL is handled:

/**
  * (1) GET http://localhost:8080/getFilename/Users/Al/tmp/file.txt
  */
get("/getFilename/*.*") {

  // (2) creates a Vector(Users/Al/tmp/file, txt)
  val data = multiParams("splat")

  // (3) prints: [Users/Al/tmp/file, txt]
  <pre>{data.mkString("[", ", ", "]")}</pre>

}

This code works because the multiParams method with the splat argument creates a Vector that contains two elements: the strings Users/Al/tmp/file and txt. Next, the information is printed back to the browser with the data.mkString line. In a real-world program, you can put the filename back together by merging data(0) and data(1), and then using the filename as needed.

There are more methods for parsing GET request parameters with Scalatra, including additional uses of wildcard characters, and Rails-like pattern matching. See the latest Scalatra documentation for more information.