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

Example: respond with 404 if None returned from server logic #4257

Merged
merged 5 commits into from
Jan 15, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions examples/src/main/scala/sttp/tapir/examples/booksExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

package sttp.tapir.examples

import sttp.model.StatusCode
import sttp.tapir.generic.auto.*

@main def booksExample(): Unit =
Expand Down Expand Up @@ -56,6 +57,16 @@ import sttp.tapir.generic.auto.*
val booksListingByGenre: PublicEndpoint[BooksQuery, String, Vector[Book], Any] = baseEndpoint.get
.in(("list" / path[String]("genre").map(Option(_))(_.get)).and(limitParameter).mapTo[BooksQuery])
.out(jsonBody[Vector[Book]])

// Optional value from serverLogic, responding with 404 when None
amorfis marked this conversation as resolved.
Show resolved Hide resolved
val singleBook = baseEndpoint.get
.in("book" / query[String]("title"))
.out(oneOf(
oneOfVariantExactMatcher(StatusCode.NotFound, jsonBody[Option[Book]])(None),
oneOfVariantValueMatcher(StatusCode.Ok, jsonBody[Option[Book]]) {
case Some(book) => true
}
))
end Endpoints

//
Expand Down Expand Up @@ -123,12 +134,18 @@ import sttp.tapir.generic.auto.*
Right[String, Vector[Book]](Library.getBooks(query))
}

def singleBookLogic(title: String): Future[Either[String, Option[Book]]] =
Future {
Right(Library.Books.get().find(_.title == title))
}

// interpreting the endpoint description and converting it to an pekko-http route, providing the logic which
// should be run when the endpoint is invoked.
List(
addBook.serverLogic(bookAddLogic.tupled),
booksListing.serverLogic(bookListingLogic),
booksListingByGenre.serverLogic(bookListingByGenreLogic)
booksListingByGenre.serverLogic(bookListingByGenreLogic),
singleBook.serverLogic(singleBookLogic)
)
end booksServerEndpoints

Expand All @@ -137,7 +154,7 @@ import sttp.tapir.generic.auto.*

// interpreting the endpoint descriptions as yaml openapi documentation
// exposing the docs using SwaggerUI endpoints, interpreted as an pekko-http route
SwaggerInterpreter().fromEndpoints(List(addBook, booksListing, booksListingByGenre), "The Tapir Library", "1.0")
SwaggerInterpreter().fromEndpoints(List(addBook, booksListing, booksListingByGenre, singleBook), "The Tapir Library", "1.0")
end swaggerUIServerEndpoints

def startServer(serverEndpoints: List[ServerEndpoint[Any, Future]]): Unit =
Expand Down
Loading