It's described actually in the book, first route requires the param, so even if you don't want to use any you need to...
/products/0
/products/1
/products/2
etc.
In second route param is optional, so it's useful when used with i.e. pager
/products
/products?page=1
/products?page=2
Of course you can create 2 routes with first approach to get the equivalent of optional param:
GET /products controllers.Application.products(page: Int ?= 0)
GET /products/:page controllers.Application.products(page: Int)
First is nicer, when you passing always the same amount of params AND all of them are required
GET /cars/:manufacturer/:model/:option controllers.Application.cars(manufacturer, model, option)
Which must be: /cars/BMW/Z4/Pure-Balance
On the other hand second route is more comfortable when you have a large amount of optional params in it
GET /filter controllers.Application.filter(query, order, direction)
which can be:
/filter?query=something&order=name&direction=desc
/filter?order=branch
/filter?query=something-else
etc.
We can't say that one is better, second is worse, just both has other usage, take a look to the docs to get familiar with optional params
, fixed values
and default values