text: (window.webpackJsonp=window.webpackJsonp||[]).push([[9],{365:function(t,a,e){"use strict";e.r(a);var s=e(44),r=Object(s.a)({},(function(){var t=this,a=t.$createElement,e=t._self._c||a;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"getting-started"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),e("p",[e("strong",[t._v("Caliban")]),t._v(" is a purely functional library for creating GraphQL servers and clients in Scala.")]),t._v(" "),e("p",[t._v("For more details on Caliban Client, see the "),e("RouterLink",{attrs:{to:"/docs/client.html"}},[t._v("dedicated section")]),t._v(". The rest of this page is about the backend part of the library.")],1),t._v(" "),e("p",[t._v("The design principles of Caliban are the following:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("pure interface")]),t._v(": errors and effects are returned explicitly (no exceptions thrown), all returned types are referentially transparent (no usage of "),e("code",[t._v("Future")]),t._v(").")]),t._v(" "),e("li",[e("strong",[t._v("minimal amount of boilerplate")]),t._v(": no need to manually define a schema for every type in your API. Let the compiler do the boring work.")]),t._v(" "),e("li",[e("strong",[t._v("excellent interoperability")]),t._v(": out-of-the-box support for major HTTP server libraries ("),e("a",{attrs:{href:"https://http4s.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("http4s"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://doc.akka.io/docs/akka-http/current/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Akka HTTP"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://www.playframework.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Play"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://github.com/finagle/finch",target:"_blank",rel:"noopener noreferrer"}},[t._v("Finch"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://github.com/dream11/zio-http",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO HTTP"),e("OutboundLink")],1),t._v("), effect types (Future, "),e("a",{attrs:{href:"https://zio.dev/",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://typelevel.org/cats-effect/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Cats Effect"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://monix.io/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Monix"),e("OutboundLink")],1),t._v("), Json libraries ("),e("a",{attrs:{href:"https://circe.github.io/circe/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Circe"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://github.com/playframework/play-json",target:"_blank",rel:"noopener noreferrer"}},[t._v("Play Json"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://github.com/zio/zio-json",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO Json"),e("OutboundLink")],1),t._v("), various integrations ("),e("a",{attrs:{href:"https://github.com/apollographql/apollo-tracing",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apollo Tracing"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://www.apollographql.com/docs/federation/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apollo Federation"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://tapir.softwaremill.com/en/latest/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Tapir"),e("OutboundLink")],1),t._v(", etc.) and more.")])]),t._v(" "),e("h2",{attrs:{id:"dependencies"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dependencies"}},[t._v("#")]),t._v(" Dependencies")]),t._v(" "),e("p",[t._v("To use "),e("code",[t._v("caliban")]),t._v(", add the following line in your "),e("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('libraryDependencies += "com.github.ghostdogpr" %% "caliban" % "1.0.1"\n')])])]),e("p",[t._v("The following modules are optional:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('libraryDependencies += "com.github.ghostdogpr" %% "caliban-http4s"     % "1.0.1" // routes for http4s\nlibraryDependencies += "com.github.ghostdogpr" %% "caliban-akka-http"  % "1.0.1" // routes for akka-http\nlibraryDependencies += "com.github.ghostdogpr" %% "caliban-play"       % "1.0.1" // routes for play\nlibraryDependencies += "com.github.ghostdogpr" %% "caliban-finch"      % "1.0.1" // routes for finch\nlibraryDependencies += "com.github.ghostdogpr" %% "caliban-zio-http"   % "1.0.1" // routes for zio-http\nlibraryDependencies += "com.github.ghostdogpr" %% "caliban-cats"       % "1.0.1" // interop with cats effect\nlibraryDependencies += "com.github.ghostdogpr" %% "caliban-monix"      % "1.0.1" // interop with monix\nlibraryDependencies += "com.github.ghostdogpr" %% "caliban-federation" % "1.0.1" // interop with apollo federation\n')])])]),e("h2",{attrs:{id:"a-simple-example"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#a-simple-example"}},[t._v("#")]),t._v(" A simple example")]),t._v(" "),e("p",[t._v("Creating a GraphQL API with Caliban is as simple as creating a case class. Indeed, the whole GraphQL schema will be derived from a case class structure (its fields and the other types it references), and the resolver is just an instance of that case class.")]),t._v(" "),e("p",[t._v("Let's say we have a class "),e("code",[t._v("Character")]),t._v(" and 2 functions: "),e("code",[t._v("getCharacters")]),t._v(" and "),e("code",[t._v("getCharacter")]),t._v(":")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Character"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getCharacters"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getCharacter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Option"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n")])])]),e("p",[t._v("Let's create a case class named "),e("code",[t._v("Queries")]),t._v(" that will represent our API, with 2 fields named and modeled after the functions we want to expose (a "),e("em",[t._v("record of functions")]),t._v("). We then create a value of this class that calls our actual functions. This is our resolver.")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// schema")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterName"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Queries"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("characters"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n                   character"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CharacterName "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Option"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// resolver")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" queries "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Queries"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getCharacters"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" args "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" getCharacter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("args"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("The next step is creating our GraphQL API definition. First, we wrap our query resolver inside a "),e("code",[t._v("RootResolver")]),t._v(", the root object that contains queries, mutations and subscriptions. Only queries are mandatory.\nThen we can call the "),e("code",[t._v("graphQL")]),t._v(" function which will turn our simple resolver value into a GraphQL API definition.\nThe whole schema will be derived at compile time, meaning that if it compiles, it will be able to serve it.")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("GraphQL"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("graphQL\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("RootResolver\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("You can use "),e("code",[t._v("api.render")]),t._v(" to visualize the schema generated, in this case:")]),t._v(" "),e("div",{staticClass:"language-graphql extra-class"},[e("pre",{pre:!0,attrs:{class:"language-graphql"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" String"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n  "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("age")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" Int"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Queries")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("characters")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n  "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("character")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" String"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" Character\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("In order to process requests, you need to turn your API into an interpreter, which can be done easily by calling "),e("code",[t._v(".interpreter")]),t._v(".\nAn interpreter is a light wrapper around the API definition that allows plugging in some middleware and possibly modifying the environment and error types (see "),e("RouterLink",{attrs:{to:"/docs/middleware.html"}},[t._v("Middleware")]),t._v(" for more info).\nCreating the interpreter may fail with a "),e("code",[t._v("ValidationError")]),t._v(" if some type is found invalid.")],1),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  interpreter "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" api"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("interpreter\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" interpreter\n")])])]),e("p",[t._v("Now you can call "),e("code",[t._v("interpreter.execute")]),t._v(" with a given GraphQL query, and you will get an "),e("code",[t._v("ZIO[R, Nothing, GraphQLResponse[CalibanError]]")]),t._v(" as a response, with "),e("code",[t._v("GraphQLResponse")]),t._v(" defined as follows:")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" GraphQLResponse"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("E"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ResponseValue"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" errors"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("E"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Use "),e("code",[t._v("ResponseValue#toString")]),t._v(" to get the JSON representation of the result.")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n  {\n    characters {\n      name\n    }\n  }"""')]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  result "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" interpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("execute"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n  _      "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" zio"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("console"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("putStrLn"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toString"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("A "),e("code",[t._v("CalibanError")]),t._v(" can be:")]),t._v(" "),e("ul",[e("li",[t._v("a "),e("code",[t._v("ParsingError")]),t._v(": the query has invalid syntax")]),t._v(" "),e("li",[t._v("a "),e("code",[t._v("ValidationError")]),t._v(": the query was parsed but does not match the schema")]),t._v(" "),e("li",[t._v("an "),e("code",[t._v("ExecutionError")]),t._v(": an error happened while executing the query")])]),t._v(" "),e("p",[t._v("Caliban itself is not tied to any web framework, you are free to expose this function using the protocol and library of your choice. The "),e("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/master/adapters/http4s",target:"_blank",rel:"noopener noreferrer"}},[t._v("caliban-http4s"),e("OutboundLink")],1),t._v(" module provides an "),e("code",[t._v("Http4sAdapter")]),t._v(" that exposes an interpreter over HTTP and WebSocket using http4s. There are also similar adapters for Akka HTTP, Play, Finch and zio-http.")]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Combining GraphQL APIs")]),t._v(" "),e("p",[t._v("You don't have to define all your root fields into a single case class: you can use smaller case classes and combine "),e("code",[t._v("GraphQL")]),t._v(" objects using the "),e("code",[t._v("|+|")]),t._v(" operator.")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api1 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api2 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" api1 "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" api2\n")])])]),e("p",[t._v("You can use "),e("code",[t._v(".rename")]),t._v(" to change the names of the generated root types.")])]),t._v(" "),e("h2",{attrs:{id:"mutations"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#mutations"}},[t._v("#")]),t._v(" Mutations")]),t._v(" "),e("p",[t._v("Creating mutations is the same as queries, except you pass them as the second argument to "),e("code",[t._v("RootResolver")]),t._v(":")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterArgs"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Mutations"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deleteCharacter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CharacterArgs "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Task"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" mutations "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Mutations"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mutations"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h2",{attrs:{id:"subscriptions"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#subscriptions"}},[t._v("#")]),t._v(" Subscriptions")]),t._v(" "),e("p",[t._v("Similarly, subscriptions are passed as the third argument to "),e("code",[t._v("RootResolver")]),t._v(":")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Subscriptions"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deletedCharacter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ZStream"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Nothing")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Character"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" subscriptions "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Subscriptions"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mutations"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" subscriptions"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("All the fields of the subscription root case class MUST return "),e("code",[t._v("ZStream")]),t._v(" or "),e("code",[t._v("? => ZStream")]),t._v(" objects. When a subscription request is received, an output stream of "),e("code",[t._v("ResponseValue")]),t._v(" (a "),e("code",[t._v("StreamValue")]),t._v(") will be returned wrapped inside an "),e("code",[t._v("ObjectValue")]),t._v(".")])])}),[],!1,null,null,null);a.default=r.exports}}]);