Library for generating and executing Graphql queries based on Sangria schemas.
resolvers += Resolver.bintrayRepo("erdeszt", "io.github.erdeszt")
libraryDependencies += "io.github.erdeszt" %% "graphient" % "7.0.0"
libraryDependencies += "io.github.erdeszt" %% "graphient-circe" % "3.0.0" // For circe support
libraryDependencies += "io.github.erdeszt" %% "graphient-spray" % "3.0.0" // For spray support
// Graphient client
import graphient._
import graphient.model._
// Graphient serializer
import graphient.serializer.circe._ // for circe support
// or
import graphient.serializer.spray._ // for spray support
Import your favorite sttp backend(in this example we'll use AsyncHttpClientCatsBackend
with IO
from cats-effect
)
Add the backend to your build:
libraryDependencies += "com.softwaremill.sttp.client" %% "async-http-client-backend-cats" % "1.6.7"
Graphient uses sttp 1.6.7
so your backend has to be compatible with it.
Create an implicit backend(the effect type has to support MonadError[?[_], Throwable]
from cats-effect
):
import cats.effect.IO
import sttp.client.asynchttpclient.cats._
implicit val sttpBackend = AsyncHttpClientCatsBackend[IO]()
Create a Graphient client with your schema (TestSchema definition):
import sttp.model._ // For the `uri` string interpolator
val client = new GraphientClient(TestSchema.schema, uri"http://yourapi.com/graphql")
-
execute via the
GraphientClient
val query = Query(TestSchema.Queries.getUser) val parameters = Map("userId", 1) val responseData = client.call[TestSchema.Domain.User](query, parameters)
responseData
is anIO[TestSchema.Domain.User]
, errors are propagated usingMonadError
fromcats-effect
-
generate the sttp request and execute it manually
val query = Query(TestSchema.Queries.getUser) val parameters = Map("userId", 1) val request = client.createRequest(query, parameters) val response = request.toOption.get.send() // Do not call .toOption.get in real code!
request
is anEither[GraphqlCallError, Request[String, Nothing]]
, you have to unwrap theEither
and execute the request manuallyresponse
is anIO[Response[String]]
Both call
and createRequest
supports adding extra headers to the request by passing in a varying number of (String, String)
values starting from position 3
client.createRequest(query, parameters, ("Authorization", "Bearer mytoken"))
client.call(query, parameters, ("Authorization", "Bearer mytoken"))
import graphient._
import graphient.model._
Create a query & a variable generator based on some Sangria schema
val queryGenerator = new QueryGenerator(TestSchema)
val variableGenerator = new VariableGenerator(TestSchema)
Generate a query or a mutation using either the schema directly or the name of the query:
val queryByDefinition = queryGenerator.generateQuery(Query(TestSchema.Queries.getUser))
val queryByName = queryGenerator.generateQuery(QueryByName("getUser"))
val mutationByDefinition = queryGenerator.generateQuery(Mutation(TestSchema.Mutations.get.createUser))
val mutationByName = queryGenerator.generateQuery(MutationByName("createUser"))
Generate variables for the query and the mutation
val variablesForGetUser = variableGenerator.generateVariables(
QueryByName("getUser"),
Map[String, Any]("userId" -> 1L)
)
val variablesForCreateUser = variableGenerator.generateVariables(
MutationByName("createUser"),
Map[String, Any](
"name" -> "user 1",
"age" -> 26,
"hobbies" -> List("coding", "debugging")
)
)
You can execute the queries in memory using a sangria.execution.Executor:
val result = Executor.execute(
schema = TestSchema,
queryAst = queryByName.right.toOption.get,
userContext = context,
variables = variablesForGetUser.right.toOption.get
)
Or pretty print it with sangria.renderer.QueryRenderer along with the variables using the sangria.marshalling.QueryAstInputUnmarshaller
val renderedQuery = QueryRenderer.render(mutationByDefinition.right.toOption.get)
// =
// mutation ($name: String!, $age: Int!, $hobbies: [String!]!) {
// createUser(name: $name, age: $age, hobbies: $hobbies) {
// id
// name
// age
// hobbies
// }
// }
val unmarshaller = new QueryAstInputUnmarshaller()
val renderedVariables = unmarshaller.render(variablesForCreateUser.right.toOption.get)
// = {name:"user 1",age:26,hobbies:["coding","debugging"]}
For further examples check graphient/src/test/scala/graphient/Worksheet.sc and the specs in grahpeint/src/test and graphient/src/it.