Andersondk7
Andersondk7

Reputation: 11

Akka HTTP Routing DSL example from documentation not working

Routing DSL in Akka HTTP does not match regular expressions correctly. I am using version 10.8.1 of Akka HTTP.

I am following the example in the documentation at https://doc.akka.io/docs/akka-http/current/routing-dsl/path-matchers.html, the example:

// matches e.g. /foo/bar123 and extracts "123" as a String
path("foo" / """bar(\d+)""".r)

Here is what I have:

2 paths and 2 routes

roles/members/01cb21e8-7368-4825-856f-c87b44b8c9a0
path("roles" / "members" / s"($uuidRegex)".r) { token =>

roles/permissions/RoleUuid:01cb21e8-7368-4825-856f-c87b44b8c9a0
path("roles" / "permissions" / s"RoleUuid:($uuidRegex)".r) { token =>

in the handler:

val uuidRegex = """[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"""

override val routes: Route = extractRequestContext { implicit rc =>
  path("roles" / "members" / s"($uuidRegex)".r) { token => 
    get { rc => 
      val method = "get role members"
      logger.info(s"RoleUUID: method(RoleUUID): $method")
      logger.info(s"RoleUUID: token: $token")
      val roleUuidOpt = Try {
        logger.info(s"RoleUUID: stringToId: converting $token")
        RoleUuid(UUID.fromString(token))
        } 
        logger.info(s"RoleUUID: roleUuid: $roleUuidOpt")
        rolesOps(rc) 
          .getMembers(roleUuidOpt.get)
          .map(x => completeStr(x.asJson.noSpaces))
        }
    } ~ 
path("roles" / "permissions" / s"RoleUuid:($uuidRegex)".r) { token =>
      get { rc =>
        val method = "get role permissions"
        logger.info(s"RoleUUID: method(RoleUUID): $method")
        logger.info(s"RoleUUID: token: $token")
        val roleUuidOpt = Try { 
          logger.info(s"RoleUUID: stringToId: converting $token")
          RoleUuid(UUID.fromString(token))
        } 
        logger.info(s"RoleUUID: roleUuid: $roleUuidOpt")
        rolesOps(rc)
          .getRolePermissions(roleUuidOpt.get)
          .map(x => completeStr(x.asJson.noSpaces))
      } 
    } 
  } 

The first path (with only the uuid)

roles/members/01cb21e8-7368-4825-856f-c87b44b8c9a0

works, that is it is matched and I see the logging statements

The second path (with the identifier and uuid) roles/permissions/RoleUuid:01cb21e8-7368-4825-856f-c87b44b8c9a0

does not work, it is not matched and I do not see the log statements since I did not see the first log statement, I'm assuming it was never matched

The only difference between the path that works and the one that does not is the prefix in the path matcher.

Upvotes: 1

Views: 2584

Answers (1)

Jeffrey Chung
Jeffrey Chung

Reputation: 19517

Use Scala's String interpolation (notice the s in front of the last path segment and the $ in front of uuidRegex):

val uuidRegex = """[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}"""

path("roles" / "members" / s"RoleId:($uuidRegex)".r) {
  // ...
}

The above path matches, for example, a call to:

http://yourhost:yourport/roles/members/RoleId:d11ffab5-ab40-4e55-9e3e-621df1992470

Upvotes: 1

Related Questions