Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Empty request path segment matching #389

Closed
goodmove opened this issue Aug 10, 2020 · 1 comment
Closed

[Bug] Empty request path segment matching #389

goodmove opened this issue Aug 10, 2020 · 1 comment
Labels
bug Something isn't working

Comments

@goodmove
Copy link

Problem

  1. Path matching behavior depends on the order, in which the endpoints are defined
  2. capture[String]('id) matches empty string in paths like /resource/{id}, but capture[Int] does not

How to reproduce

Typed Schema version: v0.12.0

Consider having two API endpoints:

  • GET /resource/{id}
  • GET /resource/

Currently, the api endpoints definition using typed-schema would be:

  def listBooks =
    prefix('books) :>
      PathEnd :>
      get :>
      key('listBooks) :>
      $$[List[String]]

  def getBook =
    prefix('books) :>
      capture[String]('bookId) :>
      PathEnd :>
      get :>
      key('getBook) :>
      $$[String]

and a handler for that could look like this:

class TestController[F[_]: Sync: RoutedPlus] { self =>
  private val books = Map(
    "1" -> "Book1",
    "2" -> "Book2",
    "3" -> "Book3",
    "4" -> "Book4",
  )

  def routes: H[Response] = MkService[H](api)(self)
  def listBooks(): List[String] = books.values.toList
  def getBook(bookId: String): String = books.getOrElse(bookId, "Not found")

}

where PathEnd checks that all symbols in the request path have been consumed.

Case 1: Definition order

1.1

Final definition:

  def api = getBook <|> listBooks

Actual:

> curl http://localhost:8080/books
< "Not found"

Expected:

> curl http://localhost:8080/books
< ["Book1","Book2","Book3","Book4"]

1.2

Final definition:

  def api = listBooks  <|> getBook

Actual matches expected

> curl http://localhost:8080/books
< ["Book1","Book2","Book3","Book4"]

Case 2: Matching inconsistency

Final definition:

  def api = getBook <|> listBooks

Let's modify getBook to accept Int:

  def getBook =
    prefix('books) :>
      capture[Int]('bookId) :>
      PathEnd :>
      get :>
      key('getBook) :>
      $$[String]

And call the API again (actual matches expected):

> curl http://localhost:8080/books
< ["Book1","Book2","Book3","Book4"]
@goodmove goodmove changed the title [Bug] Empty request path matching [Bug] Empty request path segment matching Aug 10, 2020
@Odomontois Odomontois added the bug Something isn't working label Sep 10, 2020
ulanzetz added a commit to ulanzetz/typed-schema that referenced this issue Oct 19, 2020
REDNBLACK pushed a commit that referenced this issue Oct 19, 2020
@REDNBLACK
Copy link
Collaborator

Fixed in #442

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants