E-commerce store with static URLs would kill even the most powerful server. It's why, to resolve dynamic behavior, we use HTTP parameters. GET ones are particularly useful.
Data Engineering Design Patterns

Looking for a book that defines and solves most common data engineering problems? I'm currently writing
one on that topic and the first chapters are already available in 👉
Early Release on the O'Reilly platform
I also help solve your data engineering problems 👉 contact@waitingforcode.com 📩
This article will present how to work with GET parameters in Play Framework. At the begin, we'll see how Play works with query string parameters. The second part of the article will present how GET parameters can be used in the routes definitions.
Query string parameters in Play Framework
We'll start by show how to work with query string parameter. Query string parameters are the parameters placed after "?" in the URL. For example, in http://mysite.com?param=A&name=B, query string parameters will be param=A and name=B. In Play we can get them thanks to play.mvc.Http.Request and its queryString() method. It returns a Map<String, String[]> representing query string params. We can test it in our index page by modifying the action method:
@Transactional(readOnly=true) public static Result index() { Map<String, String[]> params = ctx().request().queryString(); if (params.containsKey("categoryId")) { try { CategoryService categoryService = (CategoryService) ServicesInstances.CATEGORY_SERVICE.getService(); Category category = categoryService.getById(FromStringConverter.toInt(params.get("categoryId")[0])); Logger.debug("Found category: "+category); } catch (Exception e) { // TODO : redirect to error page } } return ok(index.render("Your new application is ready.")); }
To see how it works, you can visit http://localhost:9000/?categoryId=1. Normally, you should see the same result as in the article about database and JPA in Play Framework.
Routes with GET parameters in Play Framework
Routing is a little bit more fun than query string handling. However, they have some subtleties and to better understand them, we'll present different routing strategies in following table:
-
Subtlety: parameter type
GET /categories/:id controllers.Category.index(id: Integer) GET /categories/:id controllers.Category.index(id)
These two routes aren't equal. The first one matches to index(int id) method while the second to index(String id). It's caused by Play interpretation of parameters without defined type. The framework treats these parameters as Strings. -
Subtlety: route default value
GET /categories controllers.Category.index(id: Integer ?= 0) GET /categories/:id controllers.Category.index(id: Integer)
If the parameter is optional, we can specify its default value. If no specified, Play will ignore given parameter and put it a default value. Accordingly in our example, both /categories and /categories/3 routes will match controllers.Category.index(int id) method. The value of id in the first route will be 0 (as specified in the configuration) and 3 in the second. -
Subtlety: static values
GET /categories controllers.Category.index(id: Integer = 999)
In this case, the value of id in index(int id) method will always be 999. -
Subtlety: RegEx values
GET /categories/$id<[0-5]> controllers.Category.index(id: Integer)
In routes we can also use regular expressions. They must be written between <>. Before them we need to define the variable to which we want to apply the RegEx. In our case, the RegEx tells that index method id parameter accepts only the numbers from 0 to 5.
This articles introduced us to route management in Play Framework. We discovered how to work with query string parameters. We also saw different methods to define SEO-friendly URLs thanks to routes file.
Consulting

With nearly 16 years of experience, including 8 as data engineer, I offer expert consulting to design and optimize scalable data solutions.
As an O’Reilly author, Data+AI Summit speaker, and blogger, I bring cutting-edge insights to modernize infrastructure, build robust pipelines, and
drive data-driven decision-making. Let's transform your data challenges into opportunities—reach out to elevate your data engineering game today!
👉 contact@waitingforcode.com
đź”— past projects