From db650abf0a86935a5f5a2bc55650f10a0faab192 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Thu, 4 Jan 2024 13:06:11 +0800 Subject: [PATCH] Flesh out examples for query param handling (#107) --- .../1 - Cask: a Scala HTTP micro-framework.md | 14 +++-- .../app/src/VariableRoutes.scala | 32 ++++++++-- .../app/test/src/ExampleTests.scala | 61 ++++++++++++++++--- 3 files changed, 90 insertions(+), 17 deletions(-) diff --git a/docs/pages/1 - Cask: a Scala HTTP micro-framework.md b/docs/pages/1 - Cask: a Scala HTTP micro-framework.md index a66811bad8..5cfeeb52fd 100644 --- a/docs/pages/1 - Cask: a Scala HTTP micro-framework.md +++ b/docs/pages/1 - Cask: a Scala HTTP micro-framework.md @@ -139,10 +139,16 @@ $$$variableRoutes You can bind variables to endpoints by declaring them as parameters: these are either taken from a path-segment matcher of the same name (e.g. `postId` above), -or from query-parameters of the same name (e.g. `param` above). You can make -`param` take a `: String` to match `?param=hello`, an `: Int` for `?param=123` a -`Seq[T]` (as above) for repeated params such as `?param=hello¶m=world`, or -`: Option[T]` for cases where the `?param=hello` is optional. +or from query-parameters of the same name (e.g. `param` above). You can make `param` take + +* `param: String` to match `?param=hello` +* `param: Int` for `?param=123` +* `param: Option[T] = None` or `param: String = "DEFAULT VALUE"` for cases where the + `?param=hello` is optional. +* `param: Seq[T]` for repeated params such as `?param=hello¶m=world` with at + least one value +* `param: Seq[T] = Nil` for repeated params such as `?param=hello¶m=world` allowing + zero values If you need to capture the entire sub-path of the request, you can set the flag `subpath=true` and ask for a `request: cask.Request` (the name of the param doesn't diff --git a/example/variableRoutes/app/src/VariableRoutes.scala b/example/variableRoutes/app/src/VariableRoutes.scala index c9e55bf08d..480d047ad7 100644 --- a/example/variableRoutes/app/src/VariableRoutes.scala +++ b/example/variableRoutes/app/src/VariableRoutes.scala @@ -1,22 +1,42 @@ package app object VariableRoutes extends cask.MainRoutes{ @cask.get("/user/:userName") - def showUserProfile(userName: String) = { + def getUserProfile(userName: String) = { s"User $userName" } - @cask.get("/post/:postId") - def showPost(postId: Int, param: Seq[String]) = { - s"Post $postId $param" + @cask.get("/article/:articleId") + def getArticle(articleId: Int, param: String) = { // Mandatory query param + s"Article $articleId $param" + } + + @cask.get("/article2/:articleId") // Optional query param + def getArticleOptional(articleId: Int, param: Option[String] = None) = { + s"Article $articleId $param" + } + + @cask.get("/article3/:articleId") // Optional query param with default + def getArticleDefault(articleId: Int, param: String = "DEFAULT VALUE") = { + s"Article $articleId $param" + } + + @cask.get("/article4/:articleId") // 1-or-more query param + def getArticleSeq(articleId: Int, param: Seq[String]) = { + s"Article $articleId $param" + } + + @cask.get("/article5/:articleId") // 0-or-more query param + def getArticleOptionalSeq(articleId: Int, param: Seq[String] = Nil) = { + s"Article $articleId $param" } @cask.get("/path", subpath = true) - def showSubpath(request: cask.Request) = { + def getSubpath(request: cask.Request) = { s"Subpath ${request.remainingPathSegments}" } @cask.post("/path", subpath = true) - def postShowSubpath(request: cask.Request) = { + def postArticleSubpath(request: cask.Request) = { s"POST Subpath ${request.remainingPathSegments}" } diff --git a/example/variableRoutes/app/test/src/ExampleTests.scala b/example/variableRoutes/app/test/src/ExampleTests.scala index c818ee8126..4494c68663 100644 --- a/example/variableRoutes/app/test/src/ExampleTests.scala +++ b/example/variableRoutes/app/test/src/ExampleTests.scala @@ -27,23 +27,70 @@ object ExampleTests extends TestSuite{ assert( - requests.get(s"$host/post/123?param=xyz¶m=abc").text() == - "Post 123 ArraySeq(xyz, abc)" || - requests.get(s"$host/post/123?param=xyz¶m=abc").text() == - "Post 123 ArrayBuffer(xyz, abc)" + requests.get(s"$host/article/123?param=xyz").text() == + "Article 123 xyz" ) - requests.get(s"$host/post/123", check = false).text() ==> + requests.get(s"$host/article/123", check = false).text() ==> + """Missing argument: (param: String) + | + |Arguments provided did not match expected signature: + | + |getArticle + | articleId Int + | param String + | + |""".stripMargin + + assert( + requests.get(s"$host/article2/123?param=xyz").text() == + "Article 123 Some(xyz)" + ) + + assert( + requests.get(s"$host/article2/123").text() == + "Article 123 None" + ) + + assert( + requests.get(s"$host/article3/123?param=xyz").text() == + "Article 123 xyz" + ) + + assert( + requests.get(s"$host/article3/123").text() == + "Article 123 DEFAULT VALUE" + ) + + + assert( + requests.get(s"$host/article4/123?param=xyz¶m=abc").text() == + "Article 123 ArraySeq(xyz, abc)" || + requests.get(s"$host/article4/123?param=xyz¶m=abc").text() == + "Article 123 ArrayBuffer(xyz, abc)" + ) + + requests.get(s"$host/article4/123", check = false).text() ==> """Missing argument: (param: Seq[String]) | |Arguments provided did not match expected signature: | - |showPost - | postId Int + |getArticleSeq + | articleId Int | param Seq[String] | |""".stripMargin + assert( + requests.get(s"$host/article5/123?param=xyz¶m=abc").text() == + "Article 123 ArraySeq(xyz, abc)" || + requests.get(s"$host/article5/123?param=xyz¶m=abc").text() == + "Article 123 ArrayBuffer(xyz, abc)" + ) + assert( + requests.get(s"$host/article5/123").text() == "Article 123 List()" + ) + requests.get(s"$host/path/one/two/three").text() ==> "Subpath List(one, two, three)"