1

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.

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

the example you posted, does not work, please see the updated post

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.