Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,408 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

clue

Experimental GraphQL client for Scala and Scala.js.

Usage

1) Create a client

Either:

  • A FetchClient[F[_], S] (supporting queries and mutations), or
  • A StreamingClient[F[_], S] (supporting queries, mutations and subscriptions).

S is a type denoting the schema. It can be any type, even a phantom type. It's only used to type-match clients and operations.

Example

  import clue.*
  import cats.effect.IO

  sealed trait StarWars

  // Scala JVM and Scala.js with http4s Ember client
  import org.http4s.ember.client.EmberClientBuilder

  EmberClientBuilder
    .default[IO]
    .build
    .use: client => 
      given Backend[IO] = Http4sHttpBackend[IO](client)
      val fetchClient: FetchClient[IO, StarWars] = 
        Http4sHttpClient.of[IO, StarWars]("https://starwars.com/graphql")
    
  // Scala JVM with JDK WS client behind http4s
  import import org.http4s.jdkhttpclient.JdkWSClient

  JdkWSClient
    .simple[IO]
    .use: client =>
      given StreamingBackend[IO] = Http4sWebSocketBackend[IO](client)
      val streamingClient: StreamingClient[IO, StarWars] = 
        Http4sWebSocketClient.of[IO, StarWars]("wss://starwars.com/graphql")


  // Scala.js with default fetch/WS client
  import clue.js.*

  given Backend[IO] = AjaxJSBackend[IO]
  val fetchClient: FetchClient[IO, StarWars] = 
    FetchJsClient.of[IO, StarWars]("https://starwars.com/graphql")

  // Streaming doesn't require Apollo, it just follows the Apollo protocol for GraphQL over WS
  given StreamingBackend[IO] = WebSocketJsBackend[IO]
  val streamingClient: StreamingClient[IO, StarWars] = 
    ApolloStreamingClient.of[IO, StarWars]("wss://starwars.com/graphql")

2) Create operations

They must extend GraphQLOperation[S], defining the following members:

  val document: String

  type Variables
  type Data

  val varEncoder: io.circe.Encoder.AsObject[Variables]
  val dataDecoder: io.circe.Decoder[Data]

Example

  import io.circe._
  import io.circe.generic.semiauto._

  object CharacterQuery extends GraphQLOperation[StarWars] {
    val document = """
        query (charId: ID!) {
          character(id: $charId) {
            id
            name
          }
        }
      """

    case class Variables(charId: String)

    case class Character(id: String, name: Option[String])
    object Character {
      implicit val characterDecoder: Decoder[Character] = deriveDecoder[Character]
    }

    case class Data(character: Option[Character])

    val varEncoder: Encoder[Variables] = deriveEncoder[Variables]
    val dataDecoder: Decoder[Data] = deriveDecoder[Data]
  }

3) Invoke operations

Example

fetchClient.request(CharacterQuery)(CharacterQuery.Variables("0001"))
  .forEach(println).unsafeRunSync()

# Data(Some(Character("0001", Some("Luke"))))

About

GraphQL client for Scala.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages