Search code examples
scalaakka-http

I am not able to reach my sessions route, issue with my routing DSL code in my akka-http app


I am able to access the board route using:

wget http://127.0.0.1:9000/board

Now if I try and access my session route like this:

wget http://127.0.0.1:9000/session/getByToken

I get this error:

--2021-11-30 11:56:12-- http://localhost:9000/session/getByToken Resolving localhost (localhost)... 127.0.0.1 Connecting to localhost (localhost)|127.0.0.1|:9000... connected. HTTP request sent, awaiting response... 404 Not Found 2021-11-30 11:56:12 ERROR 404: Not Found.

What am I doing wrong with my route configuration?

Also, I want the route to eventually be called like this:

wget http://127.0.0.1:9000/session/getByToken/abc123abc123abc1234

How can I fetch a string parameter on the getByToken route also?

 val boardRoutes =
    path("board") {
        get {
        complete("board#index route")
        }
    }

    val sessionRoutes =
    concat(
        path("session") {
        path("getByToken") {
            get {
            complete("session#load route TODO add param for tokenId")
            }
        }
        path("login") {
            post {
            complete("session#login route")
            }
        }
        path("logout") {
            delete {
            complete("session#login route")
            }
        }
        }
    )

    val routes = chatRoute ~ boardRoutes ~ sessionRoutes

Solution

  • A path attempts to match the complete remaining path and nested paths are ignored. Instead, you need pathPrefix as the outermost directive. Remaining extracts the rest of the path which can be used to match tokenId.

    pathPrefix("session") {
      path("getByToken" / Remaining) { tokenId =>
        get {
          complete("session#load route TODO add param for "+ tokenId)
        }
      } ~
        path("login") {
          post {
            complete("session#login route")
          }
        } ~
        path("logout") {
          delete {
            complete("session#login route")
          }
        }
    }
    

    Also, concat chains the directives using a foldLeft, so it can be used as so:

    pathPrefix("session") {
      concat(
        path("getByToken" / Remaining) { tokenId =>
          get {
            complete("session#load route TODO add param for "+ tokenId)
          }
        },
        path("login") {
          post {
            complete("session#login route")
          }
        },
        path("logout") {
          delete {
            complete("session#login route")
          }
        }
      )
    }