Reputation: 27
I'm using Sangria for a Play application and currently struggling to implement the schema definition. The Problem is, that the service does not return the needed object directly, it returns an EitherT containing the object.
Here are some code examples
case class
case class User(name: String, age: Int)
UserService
def user(): EitherT[Future, AbstractError, User] = {...}
If the service would return a User
instead of a EitherT[Future, AbstractError, User]
I would derive the schema like this:
Schema
val UserType = deriveObjectType[UserService, User](
ObjectTypeName("User"),
ObjectTypeDescription("A simple user."))
Do I have to implement an additional layer to extract the User
from the EitherT
object or is there another way to handle this situation?
Upvotes: 0
Views: 362
Reputation: 1
You can also use an implicit conversion from cats EitherT
to a sangria FutureValue
somewhere in your schema :
implicit def eithertAction[Ctx, Val, E <: Throwable](value: EitherT[Future, E, Val]): ReduceAction[Ctx, Val] = FutureValue(value.valueOrF(Future.failed))
Upvotes: 0
Reputation: 26576
You can still derive the User
object type since it is just a simple case class. For other GraphQL fields that load the users and return EitherT
you would need to transform the value to something that sangria can work with (which means that these fields need to be defined manually, but you still can use derive*
macros for other fields). The most simple approach would be to fold it to a simple Future[User]
. Future
is able to hold the error or the success result. If you would have a list of errors inside of the Either
, then you can just wrap it in some custom exception, and then unwrap and properly render it in the ExceptionHandler
.
Upvotes: 1