Routes Matching 🔗

Routes matching design 🔗

Web frameworks do their routes matching with various mechanisms:

  • annotation + method param: Spring and most other popular Java frameworks, Cask etc
  • special route file DSL: PlayFramework, Ruby on Rails
  • in-language DSL: zio-http, akka-http
  • pattern matching: Sharaf, http4s

Why not annotations? 🔗

Let's see an example:

@GetMapping(value = "/student/{studentId}")
public Student studentData1(@PathVariable Integer studentId) {}

@GetMapping(value = "/student/{studentId}")
public Student studentData2(@PathVariable Integer studentId) {}

@GetMapping(value = "/student/umm")
public Student studentData3(@PathVariable Integer studentId) {}

Issues:

  • the studentId appears in 2 places, you can make a typo and nothing will work.
  • the "/student/{studentId}" route is duplicated, there is no compiler support and it will fail only in runtime..
  • you have to wonder if studentData1 will be picked up before studentData3..!?

Why not special route file? 🔗

Well, you need a special compiler for this, essentially a new language.
People have to learn how it works, there's probably no syntax highlighting, no autocomplete etc.

Why not in-language DSL? 🔗

Similar to special route file approach, people need to learn it.
And again, you don't leverage compiler's support like exhaustive pattern matching and extractors.

Sharaf's approach 🔗

Sharaf does its route matching in plain scala code.
Scala's pattern matching warns you when you have duplicate routes, or impossible routes.
For example, if you write this:

case GET -> Path("cars", brand) => ???
case GET -> Path("cars", model) => ??? // Unreachable case

case GET -> Path("files", segments*) => ???
case GET -> Path("files", "abc.txt") => ??? // Unreachable case

you will get nice warnings, thanks compiler!


You can extract path variables with pattern matching:

case GET -> Path("cars", param[Int](carId)) => ???

Here, the carId is parsed as Int and it mentioned only once, unlike with the annotation approach.

⬅️ Query Params Handling