From ec142b407d4ec91bf64f46724878fd383096e6be Mon Sep 17 00:00:00 2001 From: Pierre Ricadat Date: Wed, 20 Dec 2023 23:56:51 +0000 Subject: [PATCH] [ci skip] update docs --- docs/404.html | 6 +++--- docs/about/index.html | 4 ++-- docs/assets/js/24.b25a8848.js | 1 - docs/assets/js/24.fb8439e6.js | 1 + docs/assets/js/{25.52d7ccfc.js => 25.987da034.js} | 2 +- docs/assets/js/{26.8e9e0199.js => 26.208fcdf6.js} | 2 +- docs/assets/js/{27.9a9f1001.js => 27.a6d8eec1.js} | 2 +- docs/assets/js/{40.e6d4961b.js => 40.fb533a9a.js} | 2 +- docs/assets/js/{41.6ae7d8e9.js => 41.bccfe839.js} | 2 +- docs/assets/js/{42.d2292bd5.js => 42.99036692.js} | 2 +- docs/assets/js/{app.93d4a129.js => app.8f3a58d5.js} | 4 ++-- docs/docs/adapters.html | 4 ++-- docs/docs/client-codegen.html | 4 ++-- docs/docs/client.html | 4 ++-- docs/docs/examples.html | 4 ++-- docs/docs/federation.html | 4 ++-- docs/docs/index.html | 6 +++--- docs/docs/interop.html | 4 ++-- docs/docs/introspection.html | 4 ++-- docs/docs/laminext.html | 4 ++-- docs/docs/middleware.html | 4 ++-- docs/docs/optimization.html | 4 ++-- docs/docs/relay-connections.html | 4 ++-- docs/docs/schema-comparison.html | 4 ++-- docs/docs/schema-reporting.html | 4 ++-- docs/docs/schema.html | 4 ++-- docs/docs/server-codegen.html | 4 ++-- docs/docs/stitching.html | 4 ++-- docs/docs/tools.html | 4 ++-- docs/docs/validation.html | 4 ++-- docs/faq/index.html | 4 ++-- docs/index.html | 6 +++--- docs/resources/index.html | 4 ++-- 33 files changed, 60 insertions(+), 60 deletions(-) delete mode 100644 docs/assets/js/24.b25a8848.js create mode 100644 docs/assets/js/24.fb8439e6.js rename docs/assets/js/{25.52d7ccfc.js => 25.987da034.js} (99%) rename docs/assets/js/{26.8e9e0199.js => 26.208fcdf6.js} (99%) rename docs/assets/js/{27.9a9f1001.js => 27.a6d8eec1.js} (99%) rename docs/assets/js/{40.e6d4961b.js => 40.fb533a9a.js} (99%) rename docs/assets/js/{41.6ae7d8e9.js => 41.bccfe839.js} (96%) rename docs/assets/js/{42.d2292bd5.js => 42.99036692.js} (97%) rename docs/assets/js/{app.93d4a129.js => app.8f3a58d5.js} (87%) diff --git a/docs/404.html b/docs/404.html index e6f8336c03..311ced2dd1 100644 --- a/docs/404.html +++ b/docs/404.html @@ -8,13 +8,13 @@ - + -

404

Looks like we've got some broken links.
+ - + diff --git a/docs/about/index.html b/docs/about/index.html index b35dc2fa84..4ec058a6fe 100644 --- a/docs/about/index.html +++ b/docs/about/index.html @@ -8,7 +8,7 @@ - + @@ -37,6 +37,6 @@ (opens new window)

# About

Caliban is a project created by Pierre Ricadat aka @ghostdogpr (opens new window).

Current maintainers:

The name is inspired by the SF novel and tv series The Expanse (opens new window).

Thanks:

- + diff --git a/docs/assets/js/24.b25a8848.js b/docs/assets/js/24.b25a8848.js deleted file mode 100644 index 68d8fbc1df..0000000000 --- a/docs/assets/js/24.b25a8848.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{308:function(t,a,s){"use strict";s.r(a);var e=s(14),r=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[a("strong",[t._v("Caliban")]),t._v(" is a purely functional library for creating GraphQL servers and clients in Scala.")]),t._v(" "),a("p",[t._v("For more details on Caliban Client, see the "),a("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(" "),a("p",[t._v("The design principles of Caliban are the following:")]),t._v(" "),a("ul",[a("li",[a("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 "),a("code",[t._v("Future")]),t._v(").")]),t._v(" "),a("li",[a("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(" "),a("li",[a("strong",[t._v("excellent interoperability")]),t._v(": out-of-the-box support for major HTTP server libraries ("),a("a",{attrs:{href:"https://http4s.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("http4s"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://doc.akka.io/docs/akka-http/current/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Akka HTTP"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/apache/incubator-pekko-http",target:"_blank",rel:"noopener noreferrer"}},[t._v("Pekko HTTP"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://www.playframework.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Play"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/dream11/zio-http",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO HTTP"),a("OutboundLink")],1),t._v("), effect types (Future, "),a("a",{attrs:{href:"https://zio.dev/",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://typelevel.org/cats-effect/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Cats Effect"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://monix.io/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Monix"),a("OutboundLink")],1),t._v("), Json libraries ("),a("a",{attrs:{href:"https://circe.github.io/circe/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Circe"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/plokhotnyuk/jsoniter-scala",target:"_blank",rel:"noopener noreferrer"}},[t._v("Jsoniter"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/playframework/play-json",target:"_blank",rel:"noopener noreferrer"}},[t._v("Play Json"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/zio/zio-json",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO Json"),a("OutboundLink")],1),t._v("), various integrations ("),a("a",{attrs:{href:"https://github.com/apollographql/apollo-tracing",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apollo Tracing"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://www.apollographql.com/docs/federation/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apollo Federation"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://tapir.softwaremill.com/en/latest/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Tapir"),a("OutboundLink")],1),t._v(", etc.) and more.")])]),t._v(" "),a("h2",{attrs:{id:"a-simple-example"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#a-simple-example"}},[t._v("#")]),t._v(" A simple example")]),t._v(" "),a("p",[t._v("First, add the following dependency to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("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(" "),a("p",[t._v("Let's say we have a class "),a("code",[t._v("Character")]),t._v(" and 2 functions: "),a("code",[t._v("getCharacters")]),t._v(" and "),a("code",[t._v("getCharacter")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getCharacters"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Nil\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getCharacter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Option"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n")])])]),a("p",[t._v("Let's create a case class named "),a("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 "),a("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(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// schema")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("characters"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n character"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CharacterName "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Option"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// resolver")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" queries "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getCharacters"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" args "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" getCharacter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("The next step is creating our GraphQL API definition. First, we wrap our query resolver inside a "),a("code",[t._v("RootResolver")]),t._v(", the root object that contains queries, mutations and subscriptions. Only queries are mandatory.\nThen we can call the "),a("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(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("ArgBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("You can use "),a("code",[t._v("api.render")]),t._v(" to visualize the schema generated, in this case:")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("age")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("Int")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Queries")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("characters")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("character")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("In order to process requests, you need to turn your API into an interpreter, which can be done easily by calling "),a("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 "),a("RouterLink",{attrs:{to:"/docs/middleware.html"}},[t._v("Middleware")]),t._v(" for more info).\nCreating the interpreter may fail with a "),a("code",[t._v("ValidationError")]),t._v(" if some type is found invalid.")],1),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n interpreter "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("interpreter\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" interpreter\n")])])]),a("p",[t._v("Now you can call "),a("code",[t._v("interpreter.execute")]),t._v(" with a given GraphQL query, and you will get an "),a("code",[t._v("ZIO[R, Nothing, GraphQLResponse[CalibanError]]")]),t._v(" as a response, with "),a("code",[t._v("GraphQLResponse")]),t._v(" defined as follows:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" GraphQLResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("E"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ResponseValue"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" errors"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("E"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Use "),a("code",[t._v("ResponseValue#toString")]),t._v(" to get the JSON representation of the result.")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n {\n characters {\n name\n }\n }"""')]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n interpreter "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("interpreter\n result "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" interpreter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("execute"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n _ "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ZIO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("debug"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toString"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("A "),a("code",[t._v("CalibanError")]),t._v(" can be:")]),t._v(" "),a("ul",[a("li",[t._v("a "),a("code",[t._v("ParsingError")]),t._v(": the query has invalid syntax")]),t._v(" "),a("li",[t._v("a "),a("code",[t._v("ValidationError")]),t._v(": the query was parsed but does not match the schema")]),t._v(" "),a("li",[t._v("an "),a("code",[t._v("ExecutionError")]),t._v(": an error happened while executing the query")])]),t._v(" "),a("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.\nThe "),a("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/adapters/http4s",target:"_blank",rel:"noopener noreferrer"}},[t._v("caliban-http4s"),a("OutboundLink")],1),t._v(" module provides an "),a("code",[t._v("Http4sAdapter")]),t._v(" that exposes an interpreter over HTTP and WebSocket using http4s. There are also similar adapters for Akka HTTP, Pekko HTTP, Play and zio-http.\nRead more on the "),a("RouterLink",{attrs:{to:"/docs/adapters.html"}},[t._v("adapters' documentation")]),t._v(".")],1),t._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("Combining GraphQL APIs")]),t._v(" "),a("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 "),a("code",[t._v("GraphQL")]),t._v(" objects using the "),a("code",[t._v("|+|")]),t._v(" operator.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api2 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" api1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" api2\n")])])]),a("p",[t._v("You can use "),a("code",[t._v(".rename")]),t._v(" to change the names of the generated root types.")])]),t._v(" "),a("h2",{attrs:{id:"mutations"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mutations"}},[t._v("#")]),t._v(" Mutations")]),t._v(" "),a("p",[t._v("Creating mutations is the same as queries, except you pass them as the second argument to "),a("code",[t._v("RootResolver")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:nest:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Task\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterArgs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deleteCharacter"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CharacterArgs "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Task"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" mutations "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("h2",{attrs:{id:"subscriptions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#subscriptions"}},[t._v("#")]),t._v(" Subscriptions")]),t._v(" "),a("p",[t._v("Similarly, subscriptions are passed as the third argument to "),a("code",[t._v("RootResolver")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:compile-only extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("stream"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("ZStream\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Subscriptions"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deletedCharacter"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ZStream"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Nothing")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" subscriptions "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Subscriptions"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" subscriptions"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("All the fields of the subscription root case class MUST return "),a("code",[t._v("ZStream")]),t._v(" or "),a("code",[t._v("? => ZStream")]),t._v(" objects. When a subscription request is received, an output stream of "),a("code",[t._v("ResponseValue")]),t._v(" (a "),a("code",[t._v("StreamValue")]),t._v(") will be returned wrapped inside an "),a("code",[t._v("ObjectValue")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"serving-over-http"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#serving-over-http"}},[t._v("#")]),t._v(" Serving over HTTP")]),t._v(" "),a("p",[t._v("The easiest (and most performant!) way to expose your API over HTTP is to use the optional "),a("code",[t._v("caliban-quick")]),t._v(" module:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-quick"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("p",[t._v("And then you can serve your GraphQL API over HTTP using a single command:")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:compile-only extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("quick"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_ "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Adds syntax to `GraphQL`")]),t._v("\n\napi"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("runServer"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n port "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8080")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n apiPath "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/api/graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n graphiqlPath "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Some"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/graphiql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("And that's it - now you have a fully functional GraphQL server running on port 8080!")]),t._v(" "),a("h2",{attrs:{id:"interop-with-3rd-party-libraries"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#interop-with-3rd-party-libraries"}},[t._v("#")]),t._v(" Interop with 3rd-party libraries")]),t._v(" "),a("p",[t._v("If you have any specific server requirements or need to interop with other libraries, Caliban offers a wide range of modules to help you do that.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-http4s"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for http4s")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-akka-http"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for akka-http")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-play"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for play")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-zio-http"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for zio-http")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-cats"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with cats effect")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-monix"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with monix")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with tapir")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-federation"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with apollo federation")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tracing"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with zio-telemetry")]),t._v("\n")])])]),a("p",[t._v("Support for JSON encoding / decoding of the inputs and responses for tapir-based adapters is enabled by adding "),a("strong",[t._v("one")]),t._v(" of the following dependencies to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-json-circe"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Circe")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-jsoniter-scala"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Jsoniter")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-json-play"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Play JSON")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-json-zio"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ZIO JSON")]),t._v("\n")])])]),a("p",[t._v("And then later in your code (you only need one!):")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("circe"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("play"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n")])])]),a("p",[t._v("For more info on the adapters and the JSON implementations, see "),a("RouterLink",{attrs:{to:"/docs/adapters.html#json-handling"}},[t._v("here")]),t._v(".")],1)])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/24.fb8439e6.js b/docs/assets/js/24.fb8439e6.js new file mode 100644 index 0000000000..e16ea528e8 --- /dev/null +++ b/docs/assets/js/24.fb8439e6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{305:function(t,a,s){"use strict";s.r(a);var e=s(14),r=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[a("strong",[t._v("Caliban")]),t._v(" is a purely functional library for creating GraphQL servers and clients in Scala.")]),t._v(" "),a("p",[t._v("For more details on Caliban Client, see the "),a("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(" "),a("p",[t._v("The design principles of Caliban are the following:")]),t._v(" "),a("ul",[a("li",[a("strong",[t._v("high performance")]),t._v(": while every public interface is pure and immutable, library internals have been optimized for speed, providing by far the best performance of any Scala GraphQL library.")]),t._v(" "),a("li",[a("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(" "),a("li",[a("strong",[t._v("excellent interoperability")]),t._v(": out-of-the-box support for major HTTP server libraries ("),a("a",{attrs:{href:"https://http4s.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("http4s"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://doc.akka.io/docs/akka-http/current/index.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("Akka HTTP"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/apache/incubator-pekko-http",target:"_blank",rel:"noopener noreferrer"}},[t._v("Pekko HTTP"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://www.playframework.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Play"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/dream11/zio-http",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO HTTP"),a("OutboundLink")],1),t._v("), effect types (Future, "),a("a",{attrs:{href:"https://zio.dev/",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://typelevel.org/cats-effect/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Cats Effect"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://monix.io/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Monix"),a("OutboundLink")],1),t._v("), Json libraries ("),a("a",{attrs:{href:"https://circe.github.io/circe/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Circe"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/plokhotnyuk/jsoniter-scala",target:"_blank",rel:"noopener noreferrer"}},[t._v("Jsoniter"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/playframework/play-json",target:"_blank",rel:"noopener noreferrer"}},[t._v("Play Json"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://github.com/zio/zio-json",target:"_blank",rel:"noopener noreferrer"}},[t._v("ZIO Json"),a("OutboundLink")],1),t._v("), various integrations ("),a("a",{attrs:{href:"https://github.com/apollographql/apollo-tracing",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apollo Tracing"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://www.apollographql.com/docs/federation/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apollo Federation"),a("OutboundLink")],1),t._v(", "),a("a",{attrs:{href:"https://tapir.softwaremill.com/en/latest/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Tapir"),a("OutboundLink")],1),t._v(", etc.) and more.")])]),t._v(" "),a("h2",{attrs:{id:"a-simple-example"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#a-simple-example"}},[t._v("#")]),t._v(" A simple example")]),t._v(" "),a("p",[t._v("First, add the following dependency to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("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(" "),a("p",[t._v("Let's say we have a class "),a("code",[t._v("Character")]),t._v(" and 2 functions: "),a("code",[t._v("getCharacters")]),t._v(" and "),a("code",[t._v("getCharacter")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" age"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Int")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getCharacters"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Nil\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" getCharacter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Option"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n")])])]),a("p",[t._v("Let's create a case class named "),a("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 "),a("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(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// schema")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("characters"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n character"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CharacterName "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Option"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// resolver")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" queries "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("getCharacters"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" args "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" getCharacter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("The next step is creating our GraphQL API definition. First, we wrap our query resolver inside a "),a("code",[t._v("RootResolver")]),t._v(", the root object that contains queries, mutations and subscriptions. Only queries are mandatory.\nThen we can call the "),a("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(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("ArgBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("You can use "),a("code",[t._v("api.render")]),t._v(" to visualize the schema generated, in this case:")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("age")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("Int")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Queries")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("characters")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("character")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("In order to process requests, you need to turn your API into an interpreter, which can be done easily by calling "),a("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 "),a("RouterLink",{attrs:{to:"/docs/middleware.html"}},[t._v("Middleware")]),t._v(" for more info).\nCreating the interpreter may fail with a "),a("code",[t._v("ValidationError")]),t._v(" if some type is found invalid.")],1),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n interpreter "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("interpreter\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" interpreter\n")])])]),a("p",[t._v("Now you can call "),a("code",[t._v("interpreter.execute")]),t._v(" with a given GraphQL query, and you will get an "),a("code",[t._v("ZIO[R, Nothing, GraphQLResponse[CalibanError]]")]),t._v(" as a response, with "),a("code",[t._v("GraphQLResponse")]),t._v(" defined as follows:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" GraphQLResponse"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("E"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ResponseValue"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" errors"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("E"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Use "),a("code",[t._v("ResponseValue#toString")]),t._v(" to get the JSON representation of the result.")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n {\n characters {\n name\n }\n }"""')]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n interpreter "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("interpreter\n result "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" interpreter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("execute"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n _ "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ZIO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("debug"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toString"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("A "),a("code",[t._v("CalibanError")]),t._v(" can be:")]),t._v(" "),a("ul",[a("li",[t._v("a "),a("code",[t._v("ParsingError")]),t._v(": the query has invalid syntax")]),t._v(" "),a("li",[t._v("a "),a("code",[t._v("ValidationError")]),t._v(": the query was parsed but does not match the schema")]),t._v(" "),a("li",[t._v("an "),a("code",[t._v("ExecutionError")]),t._v(": an error happened while executing the query")])]),t._v(" "),a("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.\nThe "),a("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/adapters/http4s",target:"_blank",rel:"noopener noreferrer"}},[t._v("caliban-http4s"),a("OutboundLink")],1),t._v(" module provides an "),a("code",[t._v("Http4sAdapter")]),t._v(" that exposes an interpreter over HTTP and WebSocket using http4s. There are also similar adapters for Akka HTTP, Pekko HTTP, Play and zio-http.\nRead more on the "),a("RouterLink",{attrs:{to:"/docs/adapters.html"}},[t._v("adapters' documentation")]),t._v(".")],1),t._v(" "),a("div",{staticClass:"custom-block tip"},[a("p",{staticClass:"custom-block-title"},[t._v("Combining GraphQL APIs")]),t._v(" "),a("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 "),a("code",[t._v("GraphQL")]),t._v(" objects using the "),a("code",[t._v("|+|")]),t._v(" operator.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api2 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" api1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" api2\n")])])]),a("p",[t._v("You can use "),a("code",[t._v(".rename")]),t._v(" to change the names of the generated root types.")])]),t._v(" "),a("h2",{attrs:{id:"mutations"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mutations"}},[t._v("#")]),t._v(" Mutations")]),t._v(" "),a("p",[t._v("Creating mutations is the same as queries, except you pass them as the second argument to "),a("code",[t._v("RootResolver")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:nest:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Task\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterArgs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deleteCharacter"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" CharacterArgs "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" Task"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Boolean")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" mutations "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_ "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("h2",{attrs:{id:"subscriptions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#subscriptions"}},[t._v("#")]),t._v(" Subscriptions")]),t._v(" "),a("p",[t._v("Similarly, subscriptions are passed as the third argument to "),a("code",[t._v("RootResolver")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:compile-only extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("stream"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("ZStream\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Subscriptions"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("deletedCharacter"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ZStream"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Nothing")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" subscriptions "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Subscriptions"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RootResolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("queries"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" mutations"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" subscriptions"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("All the fields of the subscription root case class MUST return "),a("code",[t._v("ZStream")]),t._v(" or "),a("code",[t._v("? => ZStream")]),t._v(" objects. When a subscription request is received, an output stream of "),a("code",[t._v("ResponseValue")]),t._v(" (a "),a("code",[t._v("StreamValue")]),t._v(") will be returned wrapped inside an "),a("code",[t._v("ObjectValue")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"serving-over-http"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#serving-over-http"}},[t._v("#")]),t._v(" Serving over HTTP")]),t._v(" "),a("p",[t._v("The easiest (and most performant!) way to expose your API over HTTP is to use the optional "),a("code",[t._v("caliban-quick")]),t._v(" module:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-quick"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("p",[t._v("And then you can serve your GraphQL API over HTTP using a single command:")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:compile-only extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("quick"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_ "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Adds syntax to `GraphQL`")]),t._v("\n\napi"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("runServer"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n port "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("8080")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n apiPath "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/api/graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n graphiqlPath "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Some"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/graphiql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("And that's it - now you have a fully functional GraphQL server running on port 8080!")]),t._v(" "),a("h2",{attrs:{id:"interop-with-3rd-party-libraries"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#interop-with-3rd-party-libraries"}},[t._v("#")]),t._v(" Interop with 3rd-party libraries")]),t._v(" "),a("p",[t._v("If you have any specific server requirements or need to interop with other libraries, Caliban offers a wide range of modules to help you do that.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-http4s"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for http4s")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-akka-http"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for akka-http")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-play"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for play")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-zio-http"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// routes for zio-http")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-cats"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with cats effect")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-monix"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with monix")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with tapir")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-federation"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with apollo federation")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tracing"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// interop with zio-telemetry")]),t._v("\n")])])]),a("p",[t._v("Support for JSON encoding / decoding of the inputs and responses for tapir-based adapters is enabled by adding "),a("strong",[t._v("one")]),t._v(" of the following dependencies to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-json-circe"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Circe")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-jsoniter-scala"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Jsoniter")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-json-play"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Play JSON")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.softwaremill.sttp.tapir"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"tapir-json-zio"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1.2.11"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ZIO JSON")]),t._v("\n")])])]),a("p",[t._v("And then later in your code (you only need one!):")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("circe"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("play"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n")])])]),a("p",[t._v("For more info on the adapters and the JSON implementations, see "),a("RouterLink",{attrs:{to:"/docs/adapters.html#json-handling"}},[t._v("here")]),t._v(".")],1)])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/25.52d7ccfc.js b/docs/assets/js/25.987da034.js similarity index 99% rename from docs/assets/js/25.52d7ccfc.js rename to docs/assets/js/25.987da034.js index dd46f803eb..d65ab075ef 100644 --- a/docs/assets/js/25.52d7ccfc.js +++ b/docs/assets/js/25.987da034.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{305:function(t,e,a){"use strict";a.r(e);var s=a(14),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"http-adapters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#http-adapters"}},[t._v("#")]),t._v(" Http Adapters")]),t._v(" "),e("p",[t._v('Once you have an interpreter able to execute GraphQL queries, you usually want to expose it using an HTTP API.\nCaliban comes with a few "ready-to-use" components (called "adapters") to expose your API with the most popular HTTP libraries.')]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("`QuickAdapter`")]),t._v(" "),e("p",[t._v("Starting with v2.4.3, Caliban provides the opinionated "),e("RouterLink",{attrs:{to:"/docs/adapters.html#high-performance-quickadapter"}},[t._v("QuickAdapter")]),t._v("\nthat favours ease-of-use and performance at the expense of customizability.")],1),t._v(" "),e("p",[t._v("If you want the best possible performance, make sure to check it out!")])]),t._v(" "),e("h2",{attrs:{id:"built-in-tapir-adapters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#built-in-tapir-adapters"}},[t._v("#")]),t._v(" Built-in tapir adapters")]),t._v(" "),e("p",[t._v("Under the hood, adapters use the "),e("a",{attrs:{href:"https://tapir.softwaremill.com/en/latest/",target:"_blank",rel:"noopener noreferrer"}},[t._v("tapir"),e("OutboundLink")],1),t._v(" library, so you can easily create a custom adapter with anything that tapir supports.")]),t._v(" "),e("p",[t._v("The following adapters are provided:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("Http4sAdapter")]),t._v(" exposes a route for http4s.")]),t._v(" "),e("li",[e("code",[t._v("ZHttpAdapter")]),t._v(" exposes a route for zio-http. This one doesn't support uploads yet.")]),t._v(" "),e("li",[e("code",[t._v("PlayHttpAdapter")]),t._v(" exposes a route for play.")]),t._v(" "),e("li",[e("code",[t._v("AkkaHttpAdapter")]),t._v(" exposes a route for akka.")]),t._v(" "),e("li",[e("code",[t._v("PekkoHttpAdapter")]),t._v(" exposes a route for pekko.")])]),t._v(" "),e("p",[t._v("To use them, you first need to transform your "),e("code",[t._v("GraphQLInterpreter")]),t._v(" into a new type of interpreter that supports the protocol you want to use.\nThere are 3 of them:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("HttpInterpreter")]),t._v(" follows the "),e("a",{attrs:{href:"https://graphql.org/learn/serving-over-http/#http-methods-headers-and-body",target:"_blank",rel:"noopener noreferrer"}},[t._v("standard GraphQL protocol"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("code",[t._v("HttpUploadInterpreter")]),t._v(" follows the "),e("a",{attrs:{href:"https://github.com/jaydenseric/graphql-multipart-request-spec",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQL multipart request protocol"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("code",[t._v("WebSocketInterpreter")]),t._v(" follows the "),e("a",{attrs:{href:"https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQL WebSocket protocol"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("These interpreters expose 2 powerful methods:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("configure")]),t._v(" takes a "),e("code",[t._v("Configurator[R]")]),t._v(" which is an alias for "),e("code",[t._v("URIO[R & Scope, Unit]")]),t._v(".\nIt allows configuring the interpreter by running an effect that will run for each request and that can modify the configuration of the running fiber. Built-in configurators such as "),e("code",[t._v("Configurator.setSkipValidation")]),t._v(", "),e("code",[t._v("Configurator.setEnableIntrospection")]),t._v(" and "),e("code",[t._v("Configurator.setQueryExecution")]),t._v(" let you dynamically change the configuration of the interpreter.")]),t._v(" "),e("li",[e("code",[t._v("intercept")]),t._v(" takes an "),e("code",[t._v("Interceptor[-R1, +R]")]),t._v(" which is an alias for "),e("code",[t._v("ZLayer[R1 & ServerRequest, TapirResponse, R]")]),t._v(".\nIt is basically a more powerful version of "),e("code",[t._v("configure")]),t._v(" that gives you access to the incoming request ("),e("code",[t._v("ServerRequest")]),t._v(") and lets you modify the environment of the interpreter (from "),e("code",[t._v("R")]),t._v(" to "),e("code",[t._v("R1")]),t._v("). A typical use case would be to extract an authentication token from the request and eliminate the authentication requirement from the environment if the token is valid. See an example "),e("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/blob/series/2.x/examples/src/main/scala/example/akkahttp/AuthExampleApp.scala#L51",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")])]),t._v(" "),e("p",[t._v("In addition to that, the "),e("code",[t._v("WebSocketInterpreter")]),t._v(" constructor comes with 2 optional parameters:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("keepAliveInterval")]),t._v(" (default: empty) defines the interval for the server to send keep alive messages to the client")]),t._v(" "),e("li",[e("code",[t._v("webSocketHooks")]),t._v(" (default: empty) gives you some hooks around the WebSocket lifecycle (useful for authentication)")])]),t._v(" "),e("p",[t._v("Once your interpreter is correctly configured, you can use one of these 3 functions exposed by each built-in adapter:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("makeHttpService")]),t._v(" turns an "),e("code",[t._v("HttpInterpreter")]),t._v(" into a route for the corresponding library")]),t._v(" "),e("li",[e("code",[t._v("makeHttpUploadService")]),t._v(" turns an "),e("code",[t._v("HttpUploadInterpreter")]),t._v(" into a route for the corresponding library")]),t._v(" "),e("li",[e("code",[t._v("makeWebSocketService")]),t._v(" turns a "),e("code",[t._v("WebSocketInterpreter")]),t._v(" into a route for the corresponding library")])]),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(" graphQLInterpreter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" GraphQLInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("AuthToken"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" CalibanError"),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 comment"}},[t._v("// turn our GraphQL interpreter into an HttpInterpreter")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" noAuthInterpreter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" HttpInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("AuthToken"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" CalibanError"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" HttpInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("graphQLInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// define authentication logic (from a ServerRequest, fail or build an AuthToken)")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" auth"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ZLayer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("ServerRequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" TapirResponse"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" AuthToken"),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 comment"}},[t._v("// pass our interceptor to eliminate the AuthToken requirement from the environment")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" authInterpreter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" HttpUploadInterpreter"),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(" CalibanError"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" httpInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("intercept"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("auth"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get our route for Akka Http")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" route "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" AkkaHttpAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("default"),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("makeHttpService"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("authInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Want to use something else? Check "),e("a",{attrs:{href:"#make-your-own-adapter"}},[t._v("make your own adapter section")]),t._v("!")]),t._v(" "),e("p",[t._v("Make sure to check the "),e("RouterLink",{attrs:{to:"/docs/examples.html"}},[t._v("examples")]),t._v(" to see the adapters in action.")],1),t._v(" "),e("h2",{attrs:{id:"json-handling"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#json-handling"}},[t._v("#")]),t._v(" Json handling")]),t._v(" "),e("p",[t._v("Caliban comes with JSON encoders and decoders for the following libraries:")]),t._v(" "),e("ul",[e("li",[t._v("circe")]),t._v(" "),e("li",[t._v("jsoniter-scala (JDK 11+ only)")]),t._v(" "),e("li",[t._v("play-json")]),t._v(" "),e("li",[t._v("zio-json")])]),t._v(" "),e("p",[t._v("Since v2.1.0, the adapters are not bound to a specific JSON handler and require the user to add the "),e("RouterLink",{attrs:{to:"/docs/#interop-with-3rd-party-libraries"}},[t._v("corresponding dependency")]),t._v(" in their project and import the implicits in scope when calling the "),e("code",[t._v("makeHttpService")]),t._v(" / "),e("code",[t._v("makeHttpUploadService")]),t._v(" / "),e("code",[t._v("makeWebSocketService")]),t._v(" methods.")],1),t._v(" "),e("p",[t._v("Let's say we want to use "),e("code",[t._v("http4s")]),t._v(" as the server implementation with "),e("code",[t._v("zio-json")]),t._v(" as the json handler. Defining the http4s route is as simple as:")]),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(" http4sRoute "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),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("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zio"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n Http4sAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("makeHttpService"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("interpreter"),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("\n")])])]),e("p",[t._v("That's it! "),e("code",[t._v("http4sRoute")]),t._v(" is a valid http4s route ready to serve our API.")]),t._v(" "),e("p",[t._v("If you use another json library, you will need to create encoders and decoders for it (which is very simple, you can simply look at the existing ones).\nThe full list of JSON libraries supported by Tapir can be found "),e("a",{attrs:{href:"https://tapir.softwaremill.com/en/latest/endpoint/json.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1)]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Known issues: jsoniter-scala")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("makeHttpUploadService")]),t._v(" methods require an implicit of "),e("code",[t._v("JsonCodec[Map[String,Seq[String]]]")]),t._v(" in scope. Jsoniter does not provide\ncodecs for common types by default, which means the user needs to create one. To do so, add the "),e("code",[t._v("jsoniter-scala-macros")]),t._v(" dependency to your project and create one as:")]),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("sttp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("github"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("plokhotnyuk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter_scala"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("core"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("github"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("plokhotnyuk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter_scala"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("macros"),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(" http4sRoute "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),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("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" codec"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" JsonValueCodec"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Map"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[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(" Seq"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[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 punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" JsonCodecMaker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("make\n\n Http4sAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("makeHttpUploadService"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("interpreter"),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("\n")])])]),e("div",{staticClass:"custom-block warning"},[e("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),e("p",[t._v("To maximize performance, the "),e("strong",[t._v("jsoniter")]),t._v(" codec implementation is stack-recursive. To prevent stack overflow errors, it has a "),e("strong",[t._v("maximum depth limit of 512")]),t._v(".")]),t._v(" "),e("p",[t._v("If your schema contains recursive types and want to use the jsoniter codecs, make sure to also limit the maximum query depth using\nthe "),e("RouterLink",{attrs:{to:"/docs/middleware.html#pre-defined-wrappers"}},[t._v("maxDepth wrapper")]),t._v(".")],1)])]),t._v(" "),e("h2",{attrs:{id:"make-your-own-adapter"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#make-your-own-adapter"}},[t._v("#")]),t._v(" Make your own adapter")]),t._v(" "),e("p",[t._v("All existing adapters are actually using a common adapter under the hood, called "),e("code",[t._v("TapirAdapter")]),t._v(".")]),t._v(" "),e("p",[t._v("This adapter, available in the "),e("code",[t._v("caliban-tapir")]),t._v(" dependency which has the same 3 methods "),e("code",[t._v("makeHttpService")]),t._v(", "),e("code",[t._v("makeHttpUploadService")]),t._v(" and "),e("code",[t._v("makeWebSocketService")]),t._v(".")]),t._v(" "),e("p",[t._v("The main differences between these and the methods from the built-in adapters is that they return one or several tapir "),e("code",[t._v("ServerEndpoint")]),t._v(",\nwhich you can then pass to a tapir interpreter. The returned "),e("code",[t._v("ServerEndpoint")]),t._v(" use "),e("code",[t._v("RIO[R, *]")]),t._v(" as an effect type, but you can easily transform it to another effect type. A helper "),e("code",[t._v("convertHttpEndpointToFuture")]),t._v(" allows converting the effect type to a scala "),e("code",[t._v("Future")]),t._v(" (this is used in the Akka, Pekko, and Play interpreters).")]),t._v(" "),e("h2",{attrs:{id:"high-performance-quickadapter"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#high-performance-quickadapter"}},[t._v("#")]),t._v(" High-performance "),e("code",[t._v("QuickAdapter")])]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("QuickAdapter")]),t._v(" requires minimal setup and uses "),e("a",{attrs:{href:"https://github.com/zio/zio-http",target:"_blank",rel:"noopener noreferrer"}},[t._v("zio-http"),e("OutboundLink")],1),t._v("\nand "),e("a",{attrs:{href:"https://github.com/plokhotnyuk/jsoniter-scala",target:"_blank",rel:"noopener noreferrer"}},[t._v("jsoniter-scala"),e("OutboundLink")],1),t._v(" without tapir in order to provide the best possible performance.")]),t._v(" "),e("h3",{attrs:{id:"usage"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#usage"}},[t._v("#")]),t._v(" Usage")]),t._v(" "),e("p",[t._v("In order to use it, just add the following to your "),e("code",[t._v("build.sbt")]),t._v(" file (no other dependencies required!):")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[t._v("libraryDependencies "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-quick"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),e("p",[t._v("By adding "),e("code",[t._v("import caliban.quick._")]),t._v(", we expose a few convenient extension methods on our "),e("code",[t._v("GraphQL")]),t._v(" api.\nFor example, we can serve our GraphQL api with minimal setup via a single command:")]),t._v(" "),e("div",{staticClass:"language-scala mdoc:compile-only 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("_\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("quick"),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(" GraphQL"),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 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\napi"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("runServer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n port "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8080")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n apiPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/api/graphql"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n graphiqlPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Some"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/graphiql"')]),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("\n")])])]),e("p",[t._v("Alternatively, you can also create a zio-http "),e("code",[t._v("Handler")]),t._v(" and manually compose it into an app:")]),t._v(" "),e("div",{staticClass:"language-scala mdoc:compile-only 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("_\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("quick"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("http"),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(" GraphQL"),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 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\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 handler "),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("handler\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Alternatively, without imported syntax:")]),t._v("\n handler2 "),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"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("QuickAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("handler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Creates a handler which serves the GraphiQL API from CDN")]),t._v("\n graphiql "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" GraphiQLHandler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("handler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("apiPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/api/graphql"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" graphiqlPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/graphiql"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n app "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Routes"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Method"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ANY "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"api"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"graphql"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" handler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Method"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("GET "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"graphiql"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" graphiql\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Add more routes, apply middleware, etc.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toHttpApp\n _ "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" Server"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("serve"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("app"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("provide"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Server"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("defaultWithPort"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8080")]),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 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("h3",{attrs:{id:"customization"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#customization"}},[t._v("#")]),t._v(" Customization")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("QuickAdapter")]),t._v(" exposes the following methods that allow you to customize the server or apply middleware to the routes:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("configure")]),t._v(" which takes a "),e("code",[t._v("Configurator[R]")]),t._v(" "),e("RouterLink",{attrs:{to:"/docs/adapters.html#built-in-tapir-adapters"}},[t._v("similar to the tapir-based adapters")])],1),t._v(" "),e("li",[e("code",[t._v("handler")]),t._v(" which returns a "),e("code",[t._v("RequestHandler[R, Response]")]),t._v(" which allows to apply middleware to the API routes.\nNote that this handler is only for the api routes. To construct the graphiql handler use "),e("code",[t._v("caliban.GraphiQLHandler.handler")]),t._v(".")])]),t._v(" "),e("p",[t._v("For more info on customization and middleware, check out the "),e("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/examples/src/main/scala/example/quick",target:"_blank",rel:"noopener noreferrer"}},[t._v("adapter examples"),e("OutboundLink")],1),t._v("!")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{306:function(t,e,a){"use strict";a.r(e);var s=a(14),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"http-adapters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#http-adapters"}},[t._v("#")]),t._v(" Http Adapters")]),t._v(" "),e("p",[t._v('Once you have an interpreter able to execute GraphQL queries, you usually want to expose it using an HTTP API.\nCaliban comes with a few "ready-to-use" components (called "adapters") to expose your API with the most popular HTTP libraries.')]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("`QuickAdapter`")]),t._v(" "),e("p",[t._v("Starting with v2.4.3, Caliban provides the opinionated "),e("RouterLink",{attrs:{to:"/docs/adapters.html#high-performance-quickadapter"}},[t._v("QuickAdapter")]),t._v("\nthat favours ease-of-use and performance at the expense of customizability.")],1),t._v(" "),e("p",[t._v("If you want the best possible performance, make sure to check it out!")])]),t._v(" "),e("h2",{attrs:{id:"built-in-tapir-adapters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#built-in-tapir-adapters"}},[t._v("#")]),t._v(" Built-in tapir adapters")]),t._v(" "),e("p",[t._v("Under the hood, adapters use the "),e("a",{attrs:{href:"https://tapir.softwaremill.com/en/latest/",target:"_blank",rel:"noopener noreferrer"}},[t._v("tapir"),e("OutboundLink")],1),t._v(" library, so you can easily create a custom adapter with anything that tapir supports.")]),t._v(" "),e("p",[t._v("The following adapters are provided:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("Http4sAdapter")]),t._v(" exposes a route for http4s.")]),t._v(" "),e("li",[e("code",[t._v("ZHttpAdapter")]),t._v(" exposes a route for zio-http. This one doesn't support uploads yet.")]),t._v(" "),e("li",[e("code",[t._v("PlayHttpAdapter")]),t._v(" exposes a route for play.")]),t._v(" "),e("li",[e("code",[t._v("AkkaHttpAdapter")]),t._v(" exposes a route for akka.")]),t._v(" "),e("li",[e("code",[t._v("PekkoHttpAdapter")]),t._v(" exposes a route for pekko.")])]),t._v(" "),e("p",[t._v("To use them, you first need to transform your "),e("code",[t._v("GraphQLInterpreter")]),t._v(" into a new type of interpreter that supports the protocol you want to use.\nThere are 3 of them:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("HttpInterpreter")]),t._v(" follows the "),e("a",{attrs:{href:"https://graphql.org/learn/serving-over-http/#http-methods-headers-and-body",target:"_blank",rel:"noopener noreferrer"}},[t._v("standard GraphQL protocol"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("code",[t._v("HttpUploadInterpreter")]),t._v(" follows the "),e("a",{attrs:{href:"https://github.com/jaydenseric/graphql-multipart-request-spec",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQL multipart request protocol"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("code",[t._v("WebSocketInterpreter")]),t._v(" follows the "),e("a",{attrs:{href:"https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQL WebSocket protocol"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("These interpreters expose 2 powerful methods:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("configure")]),t._v(" takes a "),e("code",[t._v("Configurator[R]")]),t._v(" which is an alias for "),e("code",[t._v("URIO[R & Scope, Unit]")]),t._v(".\nIt allows configuring the interpreter by running an effect that will run for each request and that can modify the configuration of the running fiber. Built-in configurators such as "),e("code",[t._v("Configurator.setSkipValidation")]),t._v(", "),e("code",[t._v("Configurator.setEnableIntrospection")]),t._v(" and "),e("code",[t._v("Configurator.setQueryExecution")]),t._v(" let you dynamically change the configuration of the interpreter.")]),t._v(" "),e("li",[e("code",[t._v("intercept")]),t._v(" takes an "),e("code",[t._v("Interceptor[-R1, +R]")]),t._v(" which is an alias for "),e("code",[t._v("ZLayer[R1 & ServerRequest, TapirResponse, R]")]),t._v(".\nIt is basically a more powerful version of "),e("code",[t._v("configure")]),t._v(" that gives you access to the incoming request ("),e("code",[t._v("ServerRequest")]),t._v(") and lets you modify the environment of the interpreter (from "),e("code",[t._v("R")]),t._v(" to "),e("code",[t._v("R1")]),t._v("). A typical use case would be to extract an authentication token from the request and eliminate the authentication requirement from the environment if the token is valid. See an example "),e("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/blob/series/2.x/examples/src/main/scala/example/akkahttp/AuthExampleApp.scala#L51",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".")])]),t._v(" "),e("p",[t._v("In addition to that, the "),e("code",[t._v("WebSocketInterpreter")]),t._v(" constructor comes with 2 optional parameters:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("keepAliveInterval")]),t._v(" (default: empty) defines the interval for the server to send keep alive messages to the client")]),t._v(" "),e("li",[e("code",[t._v("webSocketHooks")]),t._v(" (default: empty) gives you some hooks around the WebSocket lifecycle (useful for authentication)")])]),t._v(" "),e("p",[t._v("Once your interpreter is correctly configured, you can use one of these 3 functions exposed by each built-in adapter:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("makeHttpService")]),t._v(" turns an "),e("code",[t._v("HttpInterpreter")]),t._v(" into a route for the corresponding library")]),t._v(" "),e("li",[e("code",[t._v("makeHttpUploadService")]),t._v(" turns an "),e("code",[t._v("HttpUploadInterpreter")]),t._v(" into a route for the corresponding library")]),t._v(" "),e("li",[e("code",[t._v("makeWebSocketService")]),t._v(" turns a "),e("code",[t._v("WebSocketInterpreter")]),t._v(" into a route for the corresponding library")])]),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(" graphQLInterpreter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" GraphQLInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("AuthToken"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" CalibanError"),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 comment"}},[t._v("// turn our GraphQL interpreter into an HttpInterpreter")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" noAuthInterpreter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" HttpInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("AuthToken"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" CalibanError"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" HttpInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("graphQLInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// define authentication logic (from a ServerRequest, fail or build an AuthToken)")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" auth"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ZLayer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("ServerRequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" TapirResponse"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" AuthToken"),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 comment"}},[t._v("// pass our interceptor to eliminate the AuthToken requirement from the environment")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" authInterpreter"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" HttpUploadInterpreter"),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(" CalibanError"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" httpInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("intercept"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("auth"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get our route for Akka Http")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" route "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" AkkaHttpAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("default"),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("makeHttpService"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("authInterpreter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Want to use something else? Check "),e("a",{attrs:{href:"#make-your-own-adapter"}},[t._v("make your own adapter section")]),t._v("!")]),t._v(" "),e("p",[t._v("Make sure to check the "),e("RouterLink",{attrs:{to:"/docs/examples.html"}},[t._v("examples")]),t._v(" to see the adapters in action.")],1),t._v(" "),e("h2",{attrs:{id:"json-handling"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#json-handling"}},[t._v("#")]),t._v(" Json handling")]),t._v(" "),e("p",[t._v("Caliban comes with JSON encoders and decoders for the following libraries:")]),t._v(" "),e("ul",[e("li",[t._v("circe")]),t._v(" "),e("li",[t._v("jsoniter-scala (JDK 11+ only)")]),t._v(" "),e("li",[t._v("play-json")]),t._v(" "),e("li",[t._v("zio-json")])]),t._v(" "),e("p",[t._v("Since v2.1.0, the adapters are not bound to a specific JSON handler and require the user to add the "),e("RouterLink",{attrs:{to:"/docs/#interop-with-3rd-party-libraries"}},[t._v("corresponding dependency")]),t._v(" in their project and import the implicits in scope when calling the "),e("code",[t._v("makeHttpService")]),t._v(" / "),e("code",[t._v("makeHttpUploadService")]),t._v(" / "),e("code",[t._v("makeWebSocketService")]),t._v(" methods.")],1),t._v(" "),e("p",[t._v("Let's say we want to use "),e("code",[t._v("http4s")]),t._v(" as the server implementation with "),e("code",[t._v("zio-json")]),t._v(" as the json handler. Defining the http4s route is as simple as:")]),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(" http4sRoute "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),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("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zio"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n Http4sAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("makeHttpService"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("interpreter"),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("\n")])])]),e("p",[t._v("That's it! "),e("code",[t._v("http4sRoute")]),t._v(" is a valid http4s route ready to serve our API.")]),t._v(" "),e("p",[t._v("If you use another json library, you will need to create encoders and decoders for it (which is very simple, you can simply look at the existing ones).\nThe full list of JSON libraries supported by Tapir can be found "),e("a",{attrs:{href:"https://tapir.softwaremill.com/en/latest/endpoint/json.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1)]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("Known issues: jsoniter-scala")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("makeHttpUploadService")]),t._v(" methods require an implicit of "),e("code",[t._v("JsonCodec[Map[String,Seq[String]]]")]),t._v(" in scope. Jsoniter does not provide\ncodecs for common types by default, which means the user needs to create one. To do so, add the "),e("code",[t._v("jsoniter-scala-macros")]),t._v(" dependency to your project and create one as:")]),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("sttp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("github"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("plokhotnyuk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter_scala"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("core"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("com"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("github"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("plokhotnyuk"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter_scala"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("macros"),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(" http4sRoute "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),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("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("tapir"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("jsoniter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" codec"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" JsonValueCodec"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Map"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[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(" Seq"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[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 punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" JsonCodecMaker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("make\n\n Http4sAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("makeHttpUploadService"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("interpreter"),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("\n")])])]),e("div",{staticClass:"custom-block warning"},[e("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),e("p",[t._v("To maximize performance, the "),e("strong",[t._v("jsoniter")]),t._v(" codec implementation is stack-recursive. To prevent stack overflow errors, it has a "),e("strong",[t._v("maximum depth limit of 512")]),t._v(".")]),t._v(" "),e("p",[t._v("If your schema contains recursive types and want to use the jsoniter codecs, make sure to also limit the maximum query depth using\nthe "),e("RouterLink",{attrs:{to:"/docs/middleware.html#pre-defined-wrappers"}},[t._v("maxDepth wrapper")]),t._v(".")],1)])]),t._v(" "),e("h2",{attrs:{id:"make-your-own-adapter"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#make-your-own-adapter"}},[t._v("#")]),t._v(" Make your own adapter")]),t._v(" "),e("p",[t._v("All existing adapters are actually using a common adapter under the hood, called "),e("code",[t._v("TapirAdapter")]),t._v(".")]),t._v(" "),e("p",[t._v("This adapter, available in the "),e("code",[t._v("caliban-tapir")]),t._v(" dependency which has the same 3 methods "),e("code",[t._v("makeHttpService")]),t._v(", "),e("code",[t._v("makeHttpUploadService")]),t._v(" and "),e("code",[t._v("makeWebSocketService")]),t._v(".")]),t._v(" "),e("p",[t._v("The main differences between these and the methods from the built-in adapters is that they return one or several tapir "),e("code",[t._v("ServerEndpoint")]),t._v(",\nwhich you can then pass to a tapir interpreter. The returned "),e("code",[t._v("ServerEndpoint")]),t._v(" use "),e("code",[t._v("RIO[R, *]")]),t._v(" as an effect type, but you can easily transform it to another effect type. A helper "),e("code",[t._v("convertHttpEndpointToFuture")]),t._v(" allows converting the effect type to a scala "),e("code",[t._v("Future")]),t._v(" (this is used in the Akka, Pekko, and Play interpreters).")]),t._v(" "),e("h2",{attrs:{id:"high-performance-quickadapter"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#high-performance-quickadapter"}},[t._v("#")]),t._v(" High-performance "),e("code",[t._v("QuickAdapter")])]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("QuickAdapter")]),t._v(" requires minimal setup and uses "),e("a",{attrs:{href:"https://github.com/zio/zio-http",target:"_blank",rel:"noopener noreferrer"}},[t._v("zio-http"),e("OutboundLink")],1),t._v("\nand "),e("a",{attrs:{href:"https://github.com/plokhotnyuk/jsoniter-scala",target:"_blank",rel:"noopener noreferrer"}},[t._v("jsoniter-scala"),e("OutboundLink")],1),t._v(" without tapir in order to provide the best possible performance.")]),t._v(" "),e("h3",{attrs:{id:"usage"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#usage"}},[t._v("#")]),t._v(" Usage")]),t._v(" "),e("p",[t._v("In order to use it, just add the following to your "),e("code",[t._v("build.sbt")]),t._v(" file (no other dependencies required!):")]),t._v(" "),e("div",{staticClass:"language-scala extra-class"},[e("pre",{pre:!0,attrs:{class:"language-scala"}},[e("code",[t._v("libraryDependencies "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-quick"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),e("p",[t._v("By adding "),e("code",[t._v("import caliban.quick._")]),t._v(", we expose a few convenient extension methods on our "),e("code",[t._v("GraphQL")]),t._v(" api.\nFor example, we can serve our GraphQL api with minimal setup via a single command:")]),t._v(" "),e("div",{staticClass:"language-scala mdoc:compile-only 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("_\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("quick"),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(" GraphQL"),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 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\napi"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("runServer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n port "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8080")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n apiPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/api/graphql"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n graphiqlPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Some"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/graphiql"')]),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("\n")])])]),e("p",[t._v("Alternatively, you can also create a zio-http "),e("code",[t._v("Handler")]),t._v(" and manually compose it into an app:")]),t._v(" "),e("div",{staticClass:"language-scala mdoc:compile-only 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("_\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("quick"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("http"),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(" GraphQL"),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 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\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 handler "),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("handler\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Alternatively, without imported syntax:")]),t._v("\n handler2 "),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"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("QuickAdapter"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("handler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Creates a handler which serves the GraphiQL API from CDN")]),t._v("\n graphiql "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" GraphiQLHandler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("handler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("apiPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/api/graphql"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" graphiqlPath "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/graphiql"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n app "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Routes"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Method"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ANY "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"api"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"graphql"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" handler"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Method"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("GET "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"graphiql"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" graphiql\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Add more routes, apply middleware, etc.")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toHttpApp\n _ "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" Server"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("serve"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("app"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("provide"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Server"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("defaultWithPort"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("8080")]),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 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("h3",{attrs:{id:"customization"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#customization"}},[t._v("#")]),t._v(" Customization")]),t._v(" "),e("p",[t._v("The "),e("code",[t._v("QuickAdapter")]),t._v(" exposes the following methods that allow you to customize the server or apply middleware to the routes:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("configure")]),t._v(" which takes a "),e("code",[t._v("Configurator[R]")]),t._v(" "),e("RouterLink",{attrs:{to:"/docs/adapters.html#built-in-tapir-adapters"}},[t._v("similar to the tapir-based adapters")])],1),t._v(" "),e("li",[e("code",[t._v("handler")]),t._v(" which returns a "),e("code",[t._v("RequestHandler[R, Response]")]),t._v(" which allows to apply middleware to the API routes.\nNote that this handler is only for the api routes. To construct the graphiql handler use "),e("code",[t._v("caliban.GraphiQLHandler.handler")]),t._v(".")])]),t._v(" "),e("p",[t._v("For more info on customization and middleware, check out the "),e("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/examples/src/main/scala/example/quick",target:"_blank",rel:"noopener noreferrer"}},[t._v("adapter examples"),e("OutboundLink")],1),t._v("!")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/26.8e9e0199.js b/docs/assets/js/26.208fcdf6.js similarity index 99% rename from docs/assets/js/26.8e9e0199.js rename to docs/assets/js/26.208fcdf6.js index 7c1ec9481b..e4ced05614 100644 --- a/docs/assets/js/26.8e9e0199.js +++ b/docs/assets/js/26.208fcdf6.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{306:function(e,a,t){"use strict";t.r(a);var n=t(14),s=Object(n.a)({},(function(){var e=this,a=e._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"code-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#code-generation"}},[e._v("#")]),e._v(" Code Generation")]),e._v(" "),a("p",[e._v("Caliban provides two sbt plugins to generate your client(s) code.")]),e._v(" "),a("p",[e._v("The first one, named "),a("code",[e._v("CalibanPlugin")]),e._v(", allows you to generate the client code from a schema file or from a server URL, manually or automatically.")]),e._v(" "),a("p",[e._v("The second one, named "),a("code",[e._v("CompileTimeCalibanPlugin")]),e._v(', allows you to generate the client code from your server code.\nThis second "meta" plugin is actually made of two "concrete" plugins, '),a("code",[e._v("CompileTimeCalibanServerPlugin")]),e._v(" and "),a("code",[e._v("CompileTimeCalibanClientPlugin")]),e._v(", that you'll\nboth need to configure in your project to be able to generate you Caliban client code from your Caliban server code.")]),e._v(" "),a("p",[e._v("To use any of these two plugins, you'll first need to add following dependency to your "),a("code",[e._v("project/plugins.sbt")]),e._v(" file:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("addSbtPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.github.ghostdogpr"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("%")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"caliban-codegen-sbt"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("%")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"2.4.3"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("h2",{attrs:{id:"calibanplugin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calibanplugin"}},[e._v("#")]),e._v(" CalibanPlugin")]),e._v(" "),a("p",[e._v("The first step for building GraphQL queries with "),a("code",[e._v("caliban-client")]),e._v(" is to generate boilerplate code from a GraphQL schema. For that, you need a file containing your schema (if your backend uses "),a("code",[e._v("caliban")]),e._v(", you can get it by calling "),a("code",[e._v("GraphQL#render")]),e._v(" on your API).")]),e._v(" "),a("p",[e._v("And enable it in your "),a("code",[e._v("build.sbt")]),e._v(" file:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CalibanPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("h3",{attrs:{id:"from-a-schema-file"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#from-a-schema-file"}},[e._v("#")]),e._v(" From a schema file")]),e._v(" "),a("p",[e._v("At this point, the "),a("code",[e._v("caliban")]),e._v(" command will cause any files in "),a("code",[e._v("src/main/graphql")]),e._v(" to be translated into a Caliban-generated client library. This happens automatically any time you "),a("code",[e._v("compile")]),e._v(".")]),e._v(" "),a("p",[e._v("By default, all clients are generated with the same client name as the source file, in the "),a("code",[e._v("caliban")]),e._v(" top-level package.")]),e._v(" "),a("p",[e._v("In order to supply more configuration options to the code generator, you can use the "),a("code",[e._v("calibanSettings")]),e._v(" sbt setting, combined with the "),a("code",[e._v("calibanSetting")]),e._v(" function to scope the settings to a particular file:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[e._v('// The `file("Service.graphql")` is a path suffix for some file in `src/main/graphql`')]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" calibanSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("+=")]),e._v(" calibanSetting"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("file"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Service.graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n cs "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("=>")]),e._v("\n cs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("packageName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.graphql.client"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("scalarMapping"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"LanguageCode"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.models.LanguageCode"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("scalarMapping"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Timestamp"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"java.sql.Timestamp"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"DayOfWeek"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"java.time.DayOfWeek"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"IntRange"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.github.tminglei.slickpg.Range[Int]"')]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("imports"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.graphql.client.implicits._"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("The path where the generator will look for schemas can be customized by overriding the "),a("code",[e._v("calibanSources")]),e._v(" settings:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" calibanSources "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" file"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"caliban"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("If you want to cherry-pick certain files yourself, you can override that as well with an explicit "),a("code",[e._v("caliban / sources")]),e._v(" entry:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" sources "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("file"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"caliban"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Service.graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("For every entry in "),a("code",[e._v("calibanSettings")]),e._v(" for the same file, a separate client (or "),a("RouterLink",{attrs:{to:"/docs/schema.html#code-generation"}},[e._v("schema")]),e._v(", depending on the entry's "),a("code",[e._v("genType")]),e._v(" value) will be generated.")],1),e._v(" "),a("h3",{attrs:{id:"from-a-server-url"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#from-a-server-url"}},[e._v("#")]),e._v(" From a server URL")]),e._v(" "),a("p",[e._v("The "),a("code",[e._v("calibanSetting")]),e._v(" function also permits generating clients for supplied "),a("code",[e._v("url")]),e._v("'s:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v(" Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" calibanSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("+=")]),e._v(" calibanSetting"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"http://my-example-service/graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n cs "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("=>")]),e._v("\n cs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("clientName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"ExampleServiceClient"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("packageName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.graphql.client"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("h3",{attrs:{id:"generation-settings"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#generation-settings"}},[e._v("#")]),e._v(" Generation settings")]),e._v(" "),a("p",[e._v("The settings available on the "),a("code",[e._v("cs")]),e._v(" ("),a("code",[e._v("CalibanSettings")]),e._v(") builder are:")]),e._v(" "),a("ul",[a("li",[a("code",[e._v("packageName")]),e._v(": The package in which the code will be generated (default: "),a("code",[e._v("caliban")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalafmtPath")]),e._v(": Path to a scalafmt config file (default: "),a("code",[e._v(".scalafmt.conf")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("genView")]),e._v(": If true, will generate a case class and helper method to select all fields on an object (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalarMappings")]),e._v(": A mapping from GraphQL scalar types to JVM types, as unknown scalar types are represented as "),a("code",[e._v("String")]),e._v(" by default.")]),e._v(" "),a("li",[a("code",[e._v("imports")]),e._v(": A list of imports to be added at the top of the generated code.")]),e._v(" "),a("li",[a("code",[e._v("splitFiles")]),e._v(": Whether to split the generated code into multiple files (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("enableFmt")]),e._v(": Enable code formatting with scalafmt (default: "),a("code",[e._v("true")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("extensibleEnums")]),e._v(": Generate a fallback case class for unknown enum values (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("headers")]),e._v(" (only defined for "),a("code",[e._v("url")]),e._v(" settings): Supply extra headers when fetching the schema from a URL.")])]),e._v(" "),a("h3",{attrs:{id:"manual-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#manual-generation"}},[e._v("#")]),e._v(" Manual generation")]),e._v(" "),a("p",[e._v("If you prefer to generate the client explicitly rather than automatically, you can use "),a("code",[e._v("calibanGenClient")]),e._v(" on the SBT CLI as follows:")]),e._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[e._v("calibanGenClient schemaPath outputPath "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--scalafmtPath path"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--headers name:value,name2:value2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--genView "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v("false"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--scalarMappings gqlType:f.q.d.n.Type,gqlType2:f.q.d.n.Type2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--imports a.b.c._,c.d.E"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--splitFiles "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v("false"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--enableFmt "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v("false"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# example")]),e._v("\ncalibanGenClient project/schema.graphql src/main/client/Client.scala "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--genView")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),e._v(" \n")])])]),a("p",[e._v("This command will generate a Scala file in "),a("code",[e._v("outputPath")]),e._v(" containing helper functions for all the types defined in the provided GraphQL schema defined at "),a("code",[e._v("schemaPath")]),e._v(".")]),e._v(" "),a("p",[e._v("If you need to disable generating clients from "),a("code",[e._v("src/main/graphql")]),e._v(", include "),a("code",[e._v("Compile / caliban / calibanGenerator := Seq.empty")]),e._v(" in your project settings.")]),e._v(" "),a("p",[e._v("The package of the generated code is derived from the folder of "),a("code",[e._v("outputPath")]),e._v(". This can be overridden by providing an alternative package with the "),a("code",[e._v("--packageName")]),e._v(" option.\nSimilarly, the generated object name is derived from "),a("code",[e._v("outputPath")]),e._v(" file name but can be overridden with the "),a("code",[e._v("--clientName")]),e._v(" option.")]),e._v(" "),a("p",[e._v("Other options are explained above.")]),e._v(" "),a("h2",{attrs:{id:"compiletimecalibanplugin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#compiletimecalibanplugin"}},[e._v("#")]),e._v(" CompileTimeCalibanPlugin")]),e._v(" "),a("p",[e._v("As mentioned in the introduction of the "),a("a",{attrs:{href:"#code-generation"}},[e._v("Code Generation")]),e._v(' chapter, this "meta" plugin is actually made of two "concrete" sbt plugins, '),a("code",[e._v("CompileTimeCalibanServerPlugin")]),e._v(" and "),a("code",[e._v("CompileTimeCalibanClientPlugin")]),e._v(",\nthat you'll both need to configure in your project be able to generate your Caliban client code from your Caliban server code..")]),e._v(" "),a("p",[e._v("You can find a demo project using this plugin here: "),a("a",{attrs:{href:"https://github.com/guizmaii/poc_compile_time_caliban_client_generation",target:"_blank",rel:"noopener noreferrer"}},[e._v("Demo project"),a("OutboundLink")],1)]),e._v(" "),a("p",[e._v("To generate the Caliban client code from you Caliban server code, you need to do two things:")]),e._v(" "),a("ol",[a("li",[a("p",[e._v("Tell to the plugin where your Caliban "),a("code",[e._v("GraphQL[R]")]),e._v(" instances for which you want to generate a client are and configure the client code generator."),a("br"),e._v("\nHow to configure this is explained in the following "),a("a",{attrs:{href:"#server-side-configuration"}},[e._v("Server side configuration")]),e._v(" chapter.")])]),e._v(" "),a("li",[a("p",[e._v("Tell to the plugin where you want to generate your client(s)."),a("br"),e._v("\nHow to configure this is explained in the following "),a("a",{attrs:{href:"#client-side-configuration"}},[e._v("Client side configuration")]),e._v(" chapter.")])])]),e._v(" "),a("h3",{attrs:{id:"server-side-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#server-side-configuration"}},[e._v("#")]),e._v(" Server side configuration")]),e._v(" "),a("p",[e._v("First, you'll need to activate the "),a("code",[e._v("CompileTimeCalibanServerPlugin")]),e._v(" plugin in all the sbt modules of your project containing a "),a("code",[e._v("GraphQL[R]")]),e._v(" instance for which you want to generate a client.")]),e._v(" "),a("p",[e._v("Let's say you have an "),a("code",[e._v("api")]),e._v(" sbt module defined in your "),a("code",[e._v("build.sbt")]),e._v(" which contains your Caliban server code:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanServerPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('Now, you need to tell to the "server side" plugin where is your '),a("code",[e._v("GraphQL[R]")]),e._v(" instance for which you want to generate a client."),a("br"),e._v("\nThis "),a("code",[e._v("GraphQL[R]")]),e._v(" instance need to be "),a("code",[e._v("public")]),e._v(". If it's "),a("code",[e._v("private")]),e._v(" or "),a("code",[e._v("protected")]),e._v(", the plugin code generator will not have access to it and will fail.")]),e._v(" "),a("p",[e._v("Let's say you have an object "),a("code",[e._v("CalibanServer")]),e._v(" object in your "),a("code",[e._v("api")]),e._v(" sbt module:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("package")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[e._v("com"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("example"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("my"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("awesome"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("project"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("api")]),e._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("import")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[e._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")])]),e._v("_\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("object")]),e._v(" CalibanServer "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n \n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" graphqlApi"),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" GraphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("MyEnv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("Resolvers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("resolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n \n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),a("p",[e._v("You'll need to add in your sbt definition:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanServerPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServer "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServerSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.my.awesome.project.api.CalibanServer.graphqlApi"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" ClientGenerationSettings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("default\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('This is the minimal working configuration for the "server side".')]),e._v(" "),a("p",[e._v("Now, you may want to tweak how the client code is generated."),a("br"),e._v("\nFor that, you'll have to replace the "),a("code",[e._v("ClientGenerationSettings.default")]),e._v(" with the configuration that suits you the best."),a("br"),e._v("\nThis "),a("code",[e._v("ClientGenerationSettings")]),e._v(" case class gives you the following configuration options:")]),e._v(" "),a("ul",[a("li",[a("code",[e._v("packageName")]),e._v(": The package in which the code will be generated (default: "),a("code",[e._v("generated")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("clientName")]),e._v(": The name of the client class generated (default: "),a("code",[e._v("Client")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalafmtPath")]),e._v(": Path to a scalafmt config file (default: "),a("code",[e._v(".scalafmt.conf")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("genView")]),e._v(": If true, will generate a case class and helper method to select all fields on an object (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalarMappings")]),e._v(": A mapping from GraphQL scalar types to JVM types, as unknown scalar types are represented as "),a("code",[e._v("String")]),e._v(" by default.")]),e._v(" "),a("li",[a("code",[e._v("imports")]),e._v(": A list of imports to be added at the top of the generated code.")]),e._v(" "),a("li",[a("code",[e._v("splitFiles")]),e._v(": Whether to split the generated code into multiple files (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("enableFmt")]),e._v(": Enable code formatting with scalafmt (default: "),a("code",[e._v("true")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("extensibleEnums")]),e._v(": Generate a fallback case class for unknown enum values (default: "),a("code",[e._v("false")]),e._v(").")])]),e._v(" "),a("p",[e._v("Let's take an example:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanServerPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServer "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServerSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.my.awesome.project.api.CalibanServer.graphqlApi"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v("\n ClientGenerationSettings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n packageName "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.my.awesome.project.client.generated"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n clientName "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"CalibanClient"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n splitFiles "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('That\'s all. You now know how to configure the "server side" of this plugin.'),a("br"),e._v('\nLet\'s now see how to configure the "client side".')]),e._v(" "),a("h3",{attrs:{id:"client-side-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#client-side-configuration"}},[e._v("#")]),e._v(" Client side configuration")]),e._v(" "),a("p",[e._v('The "client side" of this plugin is here to help you define where your Caliban client code is generated.')]),e._v(" "),a("p",[e._v("The first thing to do is to activate the "),a("code",[e._v("CompileTimeCalibanClientPlugin")]),e._v(" in the sbt module where you want your Caliban client code to be generated into.")]),e._v(" "),a("p",[e._v("Let's say you have a "),a("code",[e._v("client")]),e._v(" sbt module defined in your "),a("code",[e._v("build.sbt")]),e._v(":")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanClientPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("You only have one thing left to do."),a("br"),e._v('\nYou need to reference your "server side" sbt module (here '),a("code",[e._v("api")]),e._v(') in your "client side" sbt module (here '),a("code",[e._v("client")]),e._v(") definition so the plugin knows that you want to generate the Caliban client code for your "),a("code",[e._v("api")]),e._v(" server\nin this "),a("code",[e._v("client")]),e._v(" sbt module:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanClientPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClient "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClientsSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('This is the minimal working configuration for the "client side".')]),e._v(" "),a("p",[e._v("By default, the Caliban client code will be generated in your "),a("code",[e._v("src/main/scala")]),e._v(" directory of your "),a("code",[e._v("client")]),e._v(" sbt module."),a("br"),e._v("\nYou may prefer it not to be generated inside your - usually versioned-in-git - module code.\nFor that, the plugin provides an option to generate the code in the "),a("code",[e._v("target")]),e._v(" directory instead:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanClientPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClient "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClientsSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClient "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClientsVersionedCode "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("false")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// By default, it's true.")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("You're done. 🎉"),a("br"),e._v("\nYou can now reload your sbt config and recompile your project. Your Caliban client code will be generated during the compilation process.")]),e._v(" "),a("h3",{attrs:{id:"additional-information-about-compiletimecalibanplugin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#additional-information-about-compiletimecalibanplugin"}},[e._v("#")]),e._v(" Additional information about CompileTimeCalibanPlugin")]),e._v(" "),a("p",[e._v("As you may have seen in the "),a("a",{attrs:{href:"https://github.com/guizmaii/poc_compile_time_caliban_client_generation",target:"_blank",rel:"noopener noreferrer"}},[e._v("demo project"),a("OutboundLink")],1),e._v(", you can have more complex configurations for this plugin."),a("br"),e._v("\nYou can have more than one "),a("code",[e._v("GraphQL[R]")]),e._v(" instance per server. Each "),a("code",[e._v("GraphQL[R]")]),e._v(" instance can have its own client code generation configuration."),a("br"),e._v('\nYou can also have multiple "servers" referenced in your "client" module. The plugin will generate all the clients for all the "servers" referenced in your sbt definition.')])])}),[],!1,null,null,null);a.default=s.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{307:function(e,a,t){"use strict";t.r(a);var n=t(14),s=Object(n.a)({},(function(){var e=this,a=e._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"code-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#code-generation"}},[e._v("#")]),e._v(" Code Generation")]),e._v(" "),a("p",[e._v("Caliban provides two sbt plugins to generate your client(s) code.")]),e._v(" "),a("p",[e._v("The first one, named "),a("code",[e._v("CalibanPlugin")]),e._v(", allows you to generate the client code from a schema file or from a server URL, manually or automatically.")]),e._v(" "),a("p",[e._v("The second one, named "),a("code",[e._v("CompileTimeCalibanPlugin")]),e._v(', allows you to generate the client code from your server code.\nThis second "meta" plugin is actually made of two "concrete" plugins, '),a("code",[e._v("CompileTimeCalibanServerPlugin")]),e._v(" and "),a("code",[e._v("CompileTimeCalibanClientPlugin")]),e._v(", that you'll\nboth need to configure in your project to be able to generate you Caliban client code from your Caliban server code.")]),e._v(" "),a("p",[e._v("To use any of these two plugins, you'll first need to add following dependency to your "),a("code",[e._v("project/plugins.sbt")]),e._v(" file:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("addSbtPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.github.ghostdogpr"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("%")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"caliban-codegen-sbt"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("%")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"2.4.3"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("h2",{attrs:{id:"calibanplugin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#calibanplugin"}},[e._v("#")]),e._v(" CalibanPlugin")]),e._v(" "),a("p",[e._v("The first step for building GraphQL queries with "),a("code",[e._v("caliban-client")]),e._v(" is to generate boilerplate code from a GraphQL schema. For that, you need a file containing your schema (if your backend uses "),a("code",[e._v("caliban")]),e._v(", you can get it by calling "),a("code",[e._v("GraphQL#render")]),e._v(" on your API).")]),e._v(" "),a("p",[e._v("And enable it in your "),a("code",[e._v("build.sbt")]),e._v(" file:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CalibanPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("h3",{attrs:{id:"from-a-schema-file"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#from-a-schema-file"}},[e._v("#")]),e._v(" From a schema file")]),e._v(" "),a("p",[e._v("At this point, the "),a("code",[e._v("caliban")]),e._v(" command will cause any files in "),a("code",[e._v("src/main/graphql")]),e._v(" to be translated into a Caliban-generated client library. This happens automatically any time you "),a("code",[e._v("compile")]),e._v(".")]),e._v(" "),a("p",[e._v("By default, all clients are generated with the same client name as the source file, in the "),a("code",[e._v("caliban")]),e._v(" top-level package.")]),e._v(" "),a("p",[e._v("In order to supply more configuration options to the code generator, you can use the "),a("code",[e._v("calibanSettings")]),e._v(" sbt setting, combined with the "),a("code",[e._v("calibanSetting")]),e._v(" function to scope the settings to a particular file:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[e._v('// The `file("Service.graphql")` is a path suffix for some file in `src/main/graphql`')]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" calibanSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("+=")]),e._v(" calibanSetting"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("file"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Service.graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n cs "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("=>")]),e._v("\n cs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("packageName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.graphql.client"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("scalarMapping"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"LanguageCode"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.models.LanguageCode"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("scalarMapping"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Timestamp"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"java.sql.Timestamp"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"DayOfWeek"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"java.time.DayOfWeek"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"IntRange"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.github.tminglei.slickpg.Range[Int]"')]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("imports"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.graphql.client.implicits._"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("The path where the generator will look for schemas can be customized by overriding the "),a("code",[e._v("calibanSources")]),e._v(" settings:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" calibanSources "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" file"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"caliban"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("If you want to cherry-pick certain files yourself, you can override that as well with an explicit "),a("code",[e._v("caliban / sources")]),e._v(" entry:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v("Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" sources "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("file"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"caliban"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"Service.graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("For every entry in "),a("code",[e._v("calibanSettings")]),e._v(" for the same file, a separate client (or "),a("RouterLink",{attrs:{to:"/docs/schema.html#code-generation"}},[e._v("schema")]),e._v(", depending on the entry's "),a("code",[e._v("genType")]),e._v(" value) will be generated.")],1),e._v(" "),a("h3",{attrs:{id:"from-a-server-url"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#from-a-server-url"}},[e._v("#")]),e._v(" From a server URL")]),e._v(" "),a("p",[e._v("The "),a("code",[e._v("calibanSetting")]),e._v(" function also permits generating clients for supplied "),a("code",[e._v("url")]),e._v("'s:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[e._v(" Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" caliban "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" calibanSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("+=")]),e._v(" calibanSetting"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"http://my-example-service/graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n cs "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("=>")]),e._v("\n cs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("clientName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"ExampleServiceClient"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("packageName"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.graphql.client"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("h3",{attrs:{id:"generation-settings"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#generation-settings"}},[e._v("#")]),e._v(" Generation settings")]),e._v(" "),a("p",[e._v("The settings available on the "),a("code",[e._v("cs")]),e._v(" ("),a("code",[e._v("CalibanSettings")]),e._v(") builder are:")]),e._v(" "),a("ul",[a("li",[a("code",[e._v("packageName")]),e._v(": The package in which the code will be generated (default: "),a("code",[e._v("caliban")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalafmtPath")]),e._v(": Path to a scalafmt config file (default: "),a("code",[e._v(".scalafmt.conf")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("genView")]),e._v(": If true, will generate a case class and helper method to select all fields on an object (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalarMappings")]),e._v(": A mapping from GraphQL scalar types to JVM types, as unknown scalar types are represented as "),a("code",[e._v("String")]),e._v(" by default.")]),e._v(" "),a("li",[a("code",[e._v("imports")]),e._v(": A list of imports to be added at the top of the generated code.")]),e._v(" "),a("li",[a("code",[e._v("splitFiles")]),e._v(": Whether to split the generated code into multiple files (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("enableFmt")]),e._v(": Enable code formatting with scalafmt (default: "),a("code",[e._v("true")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("extensibleEnums")]),e._v(": Generate a fallback case class for unknown enum values (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("headers")]),e._v(" (only defined for "),a("code",[e._v("url")]),e._v(" settings): Supply extra headers when fetching the schema from a URL.")])]),e._v(" "),a("h3",{attrs:{id:"manual-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#manual-generation"}},[e._v("#")]),e._v(" Manual generation")]),e._v(" "),a("p",[e._v("If you prefer to generate the client explicitly rather than automatically, you can use "),a("code",[e._v("calibanGenClient")]),e._v(" on the SBT CLI as follows:")]),e._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[e._v("calibanGenClient schemaPath outputPath "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--scalafmtPath path"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--headers name:value,name2:value2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--genView "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v("false"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--scalarMappings gqlType:f.q.d.n.Type,gqlType2:f.q.d.n.Type2"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--imports a.b.c._,c.d.E"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--splitFiles "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v("false"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("--enableFmt "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("|")]),e._v("false"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[e._v("# example")]),e._v("\ncalibanGenClient project/schema.graphql src/main/client/Client.scala "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--genView")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),e._v(" \n")])])]),a("p",[e._v("This command will generate a Scala file in "),a("code",[e._v("outputPath")]),e._v(" containing helper functions for all the types defined in the provided GraphQL schema defined at "),a("code",[e._v("schemaPath")]),e._v(".")]),e._v(" "),a("p",[e._v("If you need to disable generating clients from "),a("code",[e._v("src/main/graphql")]),e._v(", include "),a("code",[e._v("Compile / caliban / calibanGenerator := Seq.empty")]),e._v(" in your project settings.")]),e._v(" "),a("p",[e._v("The package of the generated code is derived from the folder of "),a("code",[e._v("outputPath")]),e._v(". This can be overridden by providing an alternative package with the "),a("code",[e._v("--packageName")]),e._v(" option.\nSimilarly, the generated object name is derived from "),a("code",[e._v("outputPath")]),e._v(" file name but can be overridden with the "),a("code",[e._v("--clientName")]),e._v(" option.")]),e._v(" "),a("p",[e._v("Other options are explained above.")]),e._v(" "),a("h2",{attrs:{id:"compiletimecalibanplugin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#compiletimecalibanplugin"}},[e._v("#")]),e._v(" CompileTimeCalibanPlugin")]),e._v(" "),a("p",[e._v("As mentioned in the introduction of the "),a("a",{attrs:{href:"#code-generation"}},[e._v("Code Generation")]),e._v(' chapter, this "meta" plugin is actually made of two "concrete" sbt plugins, '),a("code",[e._v("CompileTimeCalibanServerPlugin")]),e._v(" and "),a("code",[e._v("CompileTimeCalibanClientPlugin")]),e._v(",\nthat you'll both need to configure in your project be able to generate your Caliban client code from your Caliban server code..")]),e._v(" "),a("p",[e._v("You can find a demo project using this plugin here: "),a("a",{attrs:{href:"https://github.com/guizmaii/poc_compile_time_caliban_client_generation",target:"_blank",rel:"noopener noreferrer"}},[e._v("Demo project"),a("OutboundLink")],1)]),e._v(" "),a("p",[e._v("To generate the Caliban client code from you Caliban server code, you need to do two things:")]),e._v(" "),a("ol",[a("li",[a("p",[e._v("Tell to the plugin where your Caliban "),a("code",[e._v("GraphQL[R]")]),e._v(" instances for which you want to generate a client are and configure the client code generator."),a("br"),e._v("\nHow to configure this is explained in the following "),a("a",{attrs:{href:"#server-side-configuration"}},[e._v("Server side configuration")]),e._v(" chapter.")])]),e._v(" "),a("li",[a("p",[e._v("Tell to the plugin where you want to generate your client(s)."),a("br"),e._v("\nHow to configure this is explained in the following "),a("a",{attrs:{href:"#client-side-configuration"}},[e._v("Client side configuration")]),e._v(" chapter.")])])]),e._v(" "),a("h3",{attrs:{id:"server-side-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#server-side-configuration"}},[e._v("#")]),e._v(" Server side configuration")]),e._v(" "),a("p",[e._v("First, you'll need to activate the "),a("code",[e._v("CompileTimeCalibanServerPlugin")]),e._v(" plugin in all the sbt modules of your project containing a "),a("code",[e._v("GraphQL[R]")]),e._v(" instance for which you want to generate a client.")]),e._v(" "),a("p",[e._v("Let's say you have an "),a("code",[e._v("api")]),e._v(" sbt module defined in your "),a("code",[e._v("build.sbt")]),e._v(" which contains your Caliban server code:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanServerPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('Now, you need to tell to the "server side" plugin where is your '),a("code",[e._v("GraphQL[R]")]),e._v(" instance for which you want to generate a client."),a("br"),e._v("\nThis "),a("code",[e._v("GraphQL[R]")]),e._v(" instance need to be "),a("code",[e._v("public")]),e._v(". If it's "),a("code",[e._v("private")]),e._v(" or "),a("code",[e._v("protected")]),e._v(", the plugin code generator will not have access to it and will fail.")]),e._v(" "),a("p",[e._v("Let's say you have an object "),a("code",[e._v("CalibanServer")]),e._v(" object in your "),a("code",[e._v("api")]),e._v(" sbt module:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("package")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[e._v("com"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("example"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("my"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("awesome"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("project"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("api")]),e._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("import")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[e._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")])]),e._v("_\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("object")]),e._v(" CalibanServer "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n \n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" graphqlApi"),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" GraphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("[")]),e._v("MyEnv"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("]")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" graphQL"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("Resolvers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("resolver"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n \n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),a("p",[e._v("You'll need to add in your sbt definition:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanServerPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServer "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServerSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.my.awesome.project.api.CalibanServer.graphqlApi"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v(" ClientGenerationSettings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("default\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('This is the minimal working configuration for the "server side".')]),e._v(" "),a("p",[e._v("Now, you may want to tweak how the client code is generated."),a("br"),e._v("\nFor that, you'll have to replace the "),a("code",[e._v("ClientGenerationSettings.default")]),e._v(" with the configuration that suits you the best."),a("br"),e._v("\nThis "),a("code",[e._v("ClientGenerationSettings")]),e._v(" case class gives you the following configuration options:")]),e._v(" "),a("ul",[a("li",[a("code",[e._v("packageName")]),e._v(": The package in which the code will be generated (default: "),a("code",[e._v("generated")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("clientName")]),e._v(": The name of the client class generated (default: "),a("code",[e._v("Client")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalafmtPath")]),e._v(": Path to a scalafmt config file (default: "),a("code",[e._v(".scalafmt.conf")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("genView")]),e._v(": If true, will generate a case class and helper method to select all fields on an object (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("scalarMappings")]),e._v(": A mapping from GraphQL scalar types to JVM types, as unknown scalar types are represented as "),a("code",[e._v("String")]),e._v(" by default.")]),e._v(" "),a("li",[a("code",[e._v("imports")]),e._v(": A list of imports to be added at the top of the generated code.")]),e._v(" "),a("li",[a("code",[e._v("splitFiles")]),e._v(": Whether to split the generated code into multiple files (default: "),a("code",[e._v("false")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("enableFmt")]),e._v(": Enable code formatting with scalafmt (default: "),a("code",[e._v("true")]),e._v(").")]),e._v(" "),a("li",[a("code",[e._v("extensibleEnums")]),e._v(": Generate a fallback case class for unknown enum values (default: "),a("code",[e._v("false")]),e._v(").")])]),e._v(" "),a("p",[e._v("Let's take an example:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" api "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanServerPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServer "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanServerSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.my.awesome.project.api.CalibanServer.graphqlApi"')]),e._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("->")]),e._v("\n ClientGenerationSettings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n packageName "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"com.example.my.awesome.project.client.generated"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n clientName "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[e._v('"CalibanClient"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n splitFiles "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("true")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('That\'s all. You now know how to configure the "server side" of this plugin.'),a("br"),e._v('\nLet\'s now see how to configure the "client side".')]),e._v(" "),a("h3",{attrs:{id:"client-side-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#client-side-configuration"}},[e._v("#")]),e._v(" Client side configuration")]),e._v(" "),a("p",[e._v('The "client side" of this plugin is here to help you define where your Caliban client code is generated.')]),e._v(" "),a("p",[e._v("The first thing to do is to activate the "),a("code",[e._v("CompileTimeCalibanClientPlugin")]),e._v(" in the sbt module where you want your Caliban client code to be generated into.")]),e._v(" "),a("p",[e._v("Let's say you have a "),a("code",[e._v("client")]),e._v(" sbt module defined in your "),a("code",[e._v("build.sbt")]),e._v(":")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanClientPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("You only have one thing left to do."),a("br"),e._v('\nYou need to reference your "server side" sbt module (here '),a("code",[e._v("api")]),e._v(') in your "client side" sbt module (here '),a("code",[e._v("client")]),e._v(") definition so the plugin knows that you want to generate the Caliban client code for your "),a("code",[e._v("api")]),e._v(" server\nin this "),a("code",[e._v("client")]),e._v(" sbt module:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanClientPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClient "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClientsSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v('This is the minimal working configuration for the "client side".')]),e._v(" "),a("p",[e._v("By default, the Caliban client code will be generated in your "),a("code",[e._v("src/main/scala")]),e._v(" directory of your "),a("code",[e._v("client")]),e._v(" sbt module."),a("br"),e._v("\nYou may prefer it not to be generated inside your - usually versioned-in-git - module code.\nFor that, the plugin provides an option to generate the code in the "),a("code",[e._v("target")]),e._v(" directory instead:")]),e._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("lazy")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("val")]),e._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v("\n project\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("CompileTimeCalibanClientPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),e._v("settings"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClient "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClientsSettings "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" Seq"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),e._v("api"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n Compile "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClient "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("/")]),e._v(" ctCalibanClientsVersionedCode "),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),a("span",{pre:!0,attrs:{class:"token operator"}},[e._v("=")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[e._v("false")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// By default, it's true.")]),e._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),e._v("\n")])])]),a("p",[e._v("You're done. 🎉"),a("br"),e._v("\nYou can now reload your sbt config and recompile your project. Your Caliban client code will be generated during the compilation process.")]),e._v(" "),a("h3",{attrs:{id:"additional-information-about-compiletimecalibanplugin"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#additional-information-about-compiletimecalibanplugin"}},[e._v("#")]),e._v(" Additional information about CompileTimeCalibanPlugin")]),e._v(" "),a("p",[e._v("As you may have seen in the "),a("a",{attrs:{href:"https://github.com/guizmaii/poc_compile_time_caliban_client_generation",target:"_blank",rel:"noopener noreferrer"}},[e._v("demo project"),a("OutboundLink")],1),e._v(", you can have more complex configurations for this plugin."),a("br"),e._v("\nYou can have more than one "),a("code",[e._v("GraphQL[R]")]),e._v(" instance per server. Each "),a("code",[e._v("GraphQL[R]")]),e._v(" instance can have its own client code generation configuration."),a("br"),e._v('\nYou can also have multiple "servers" referenced in your "client" module. The plugin will generate all the clients for all the "servers" referenced in your sbt definition.')])])}),[],!1,null,null,null);a.default=s.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/27.9a9f1001.js b/docs/assets/js/27.a6d8eec1.js similarity index 99% rename from docs/assets/js/27.9a9f1001.js rename to docs/assets/js/27.a6d8eec1.js index bb9627cfae..2449b15162 100644 --- a/docs/assets/js/27.9a9f1001.js +++ b/docs/assets/js/27.a6d8eec1.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{307:function(t,a,s){"use strict";s.r(a);var e=s(14),n=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[a("strong",[t._v("Caliban Client")]),t._v(" is a module independent from Caliban Server that makes it possible to write GraphQL queries using Scala code in a type-safe and functional fashion. It is built on top of "),a("a",{attrs:{href:"https://github.com/softwaremill/sttp",target:"_blank",rel:"noopener noreferrer"}},[t._v("sttp"),a("OutboundLink")],1),t._v(", which means you can run requests using the backend of your choice.")]),t._v(" "),a("p",[t._v("Just like the server module, Caliban Client offers a purely functional interface and keeps the boilerplate minimal. It works as follows:")]),t._v(" "),a("ol",[a("li",[t._v("Use the "),a("code",[t._v("caliban-codegen-sbt")]),t._v(" tool to generate boilerplate code from a given GraphQL schema")]),t._v(" "),a("li",[t._v("Write your GraphQL queries/mutations by combining helpers from the generated code")]),t._v(" "),a("li",[t._v("Transform your queries/mutations into an "),a("code",[t._v("sttp")]),t._v(" request and run them with your preferred backend")])]),t._v(" "),a("h2",{attrs:{id:"dependencies"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#dependencies"}},[t._v("#")]),t._v(" Dependencies")]),t._v(" "),a("p",[t._v("To use "),a("code",[t._v("caliban-client")]),t._v(", add the following dependency to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-client"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("p",[t._v("Caliban-client is available for ScalaJS. To use it in a ScalaJS project, instead add this dependency to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-client"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("h2",{attrs:{id:"code-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#code-generation"}},[t._v("#")]),t._v(" Code generation")]),t._v(" "),a("p",[t._v("Caliban provides several ways to generate the boilerplate code. To get started, we are going to generate it by running a\nsimple sbt command, but you can look at the "),a("RouterLink",{attrs:{to:"/docs/client-codegen.html"}},[t._v("Code generation")]),t._v(" page for more options.")],1),t._v(" "),a("p",[t._v("You'll first need to add following dependency to your "),a("code",[t._v("project/plugins.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[t._v("addSbtPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-codegen-sbt"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("And to enable the plugin in your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[t._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CalibanPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Then, you can run the following command in your sbt.")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("calibanGenClient schemaPath outputPath\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# example")]),t._v("\ncalibanGenClient project/schema.graphql src/main/client/Client.scala\n")])])]),a("p",[a("code",[t._v("schemaPath")]),t._v(" is the path to a GraphQL schema file (if your backend uses "),a("code",[t._v("caliban")]),t._v(", you can get it by calling "),a("code",[t._v("GraphQL#render")]),t._v(" on your API).\nInstead of a file, you can provide a URL and the schema will be obtained using introspection.")]),t._v(" "),a("p",[a("code",[t._v("outputPath")]),t._v(" is the path where the generated code will be written. The folder needs to exist.")]),t._v(" "),a("p",[t._v("This command will generate a Scala file in "),a("code",[t._v("outputPath")]),t._v(" containing helper functions for all the types defined in the provided GraphQL schema defined at "),a("code",[t._v("schemaPath")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"query-building"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#query-building"}},[t._v("#")]),t._v(" Query building")]),t._v(" "),a("p",[t._v("Once the boilerplate code is generated, you can start building queries. For each "),a("em",[t._v("type")]),t._v(" in your schema, a corresponding Scala object has been created. For each "),a("em",[t._v("field")]),t._v(" in your schema, a corresponding Scala function has been created.")]),t._v(" "),a("p",[t._v("For example, given the following schema:")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("nicknames")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("origin")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Origin")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Your generated code will have the following:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Character "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" nicknames"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" origin"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("A "),a("code",[t._v("SelectionBuilder[Origin, A]")]),t._v(" is a selection from a parent type "),a("code",[t._v("Origin")]),t._v(" that returns a result of type "),a("code",[t._v("A")]),t._v(". In this example, "),a("code",[t._v("name")]),t._v(" is a selection from a "),a("code",[t._v("Character")]),t._v(" that returns a "),a("code",[t._v("String")]),t._v(".")]),t._v(" "),a("p",[t._v("You can combine multiple selections using the "),a("code",[t._v("~")]),t._v(" operator. The new result type will be a tuple from the 2 combined result types. Note that you can only combine selections that have the same origin.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" selection"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nicknames\n")])])]),a("p",[t._v("If you combine multiple fields, it is more convenient to have a case class to represent your data (to avoid seeing nested tuples). You can use "),a("code",[t._v("mapN")]),t._v(" to map a nested tuple to a case class.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" nickname"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" origin"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" character"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nicknames "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("mapN"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Fields that return an object type will require an inner selection, which is another "),a("code",[t._v("SelectionBuilder")]),t._v(". Let's consider the following "),a("code",[t._v("Query")]),t._v(" type.")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Query")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("characters")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("When calling "),a("code",[t._v("characters")]),t._v(", we need to provide a "),a("code",[t._v("SelectionBuilder[Character, ?]")]),t._v(" to indicate which fields to select on the returned "),a("code",[t._v("Character")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("RootQuery"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("characters "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nicknames "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("mapN"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Or if we reuse the "),a("code",[t._v("character")]),t._v(" selection we just created:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("RootQuery"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("characters "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n character\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Because this is Scala code, you can easily reuse a selection in multiple places without having to worry about GraphQL fragments. The Scala compiler will also make sure that you only combine fields that make sense.")]),t._v(" "),a("p",[t._v("When a field requires an argument, the helper method for the field will require one as well. Let's enrich our query:")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Query")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("characters")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("origin")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Origin")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("You now need to provide an "),a("code",[t._v("Origin")]),t._v(" when calling "),a("code",[t._v("characters")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("RootQuery"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("characters"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("MARS"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n character\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"request-execution"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#request-execution"}},[t._v("#")]),t._v(" Request execution")]),t._v(" "),a("p",[t._v("Once your query or mutation is created, it is time to execute it. To do that, you can transform your "),a("code",[t._v("SelectionBuilder")]),t._v(" into an "),a("code",[t._v("sttp")]),t._v(" request by calling "),a("code",[t._v(".toRequest")]),t._v(".")]),t._v(" "),a("p",[t._v("This function takes the URL of your GraphQL server and some options:")]),t._v(" "),a("ul",[a("li",[t._v("a boolean "),a("code",[t._v("useVariables")]),t._v(" that determines if arguments should be using variables or not (default: false)")]),t._v(" "),a("li",[t._v("an optional string "),a("code",[t._v("queryName")]),t._v(" if you want to name your query (default: no name)")]),t._v(" "),a("li",[t._v("a boolean "),a("code",[t._v("dropNullInputValues")]),t._v(" that determines if null fields from input objects should be dropped (default: false)")])]),t._v(" "),a("p",[t._v("You can then simply run the "),a("code",[t._v("sttp")]),t._v(" request with the backend of your choice. See the "),a("a",{attrs:{href:"https://sttp.readthedocs.io/en/latest/",target:"_blank",rel:"noopener noreferrer"}},[t._v("sttp docs"),a("OutboundLink")],1),t._v(" if you are not familiar with it.")]),t._v(" "),a("p",[t._v("Here is an example using the "),a("code",[t._v("AsyncHttpClient")]),t._v(" backend for "),a("code",[t._v("ZIO")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("client3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("client3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asynchttpclient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("AsyncHttpClientZioBackend\n\nAsyncHttpClientZioBackend"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("flatMap "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" backend "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" serverUrl "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-interpolation"}},[a("span",{pre:!0,attrs:{class:"token id function"}},[t._v("uri")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://localhost:8088/api/graphql"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" result"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Task"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toRequest"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("serverUrl"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("send"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("absolve\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("As a result, we get a ZIO "),a("code",[t._v("Task")]),t._v(" whose return type is the same as our "),a("code",[t._v("SelectionBuilder")]),t._v(". The sttp request does not only contain the request to send, but also takes care of parsing the response into the expected type.")]),t._v(" "),a("p",[t._v("The "),a("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/examples/",target:"_blank",rel:"noopener noreferrer"}},[t._v("examples"),a("OutboundLink")],1),t._v(" project contains a runnable sample code that queries the example GraphQL backend.")]),t._v(" "),a("div",{staticClass:"custom-block warning"},[a("p",{staticClass:"custom-block-title"},[t._v("Limitations")]),t._v(" "),a("p",[t._v("Only Queries and Mutations are supported as sttp requests.\nSubscriptions are supported in the laminext module, and this code can easily be adapted to other frameworks (the relevant code is only a few lines long).")]),t._v(" "),a("p",[t._v("Type extensions are not supported by the codegen tool.")])])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{308:function(t,a,s){"use strict";s.r(a);var e=s(14),n=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"getting-started"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),a("p",[a("strong",[t._v("Caliban Client")]),t._v(" is a module independent from Caliban Server that makes it possible to write GraphQL queries using Scala code in a type-safe and functional fashion. It is built on top of "),a("a",{attrs:{href:"https://github.com/softwaremill/sttp",target:"_blank",rel:"noopener noreferrer"}},[t._v("sttp"),a("OutboundLink")],1),t._v(", which means you can run requests using the backend of your choice.")]),t._v(" "),a("p",[t._v("Just like the server module, Caliban Client offers a purely functional interface and keeps the boilerplate minimal. It works as follows:")]),t._v(" "),a("ol",[a("li",[t._v("Use the "),a("code",[t._v("caliban-codegen-sbt")]),t._v(" tool to generate boilerplate code from a given GraphQL schema")]),t._v(" "),a("li",[t._v("Write your GraphQL queries/mutations by combining helpers from the generated code")]),t._v(" "),a("li",[t._v("Transform your queries/mutations into an "),a("code",[t._v("sttp")]),t._v(" request and run them with your preferred backend")])]),t._v(" "),a("h2",{attrs:{id:"dependencies"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#dependencies"}},[t._v("#")]),t._v(" Dependencies")]),t._v(" "),a("p",[t._v("To use "),a("code",[t._v("caliban-client")]),t._v(", add the following dependency to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-client"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("p",[t._v("Caliban-client is available for ScalaJS. To use it in a ScalaJS project, instead add this dependency to your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-client"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),a("h2",{attrs:{id:"code-generation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#code-generation"}},[t._v("#")]),t._v(" Code generation")]),t._v(" "),a("p",[t._v("Caliban provides several ways to generate the boilerplate code. To get started, we are going to generate it by running a\nsimple sbt command, but you can look at the "),a("RouterLink",{attrs:{to:"/docs/client-codegen.html"}},[t._v("Code generation")]),t._v(" page for more options.")],1),t._v(" "),a("p",[t._v("You'll first need to add following dependency to your "),a("code",[t._v("project/plugins.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[t._v("addSbtPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-codegen-sbt"')]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("And to enable the plugin in your "),a("code",[t._v("build.sbt")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[t._v("enablePlugins"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CalibanPlugin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Then, you can run the following command in your sbt.")]),t._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[t._v("calibanGenClient schemaPath outputPath\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# example")]),t._v("\ncalibanGenClient project/schema.graphql src/main/client/Client.scala\n")])])]),a("p",[a("code",[t._v("schemaPath")]),t._v(" is the path to a GraphQL schema file (if your backend uses "),a("code",[t._v("caliban")]),t._v(", you can get it by calling "),a("code",[t._v("GraphQL#render")]),t._v(" on your API).\nInstead of a file, you can provide a URL and the schema will be obtained using introspection.")]),t._v(" "),a("p",[a("code",[t._v("outputPath")]),t._v(" is the path where the generated code will be written. The folder needs to exist.")]),t._v(" "),a("p",[t._v("This command will generate a Scala file in "),a("code",[t._v("outputPath")]),t._v(" containing helper functions for all the types defined in the provided GraphQL schema defined at "),a("code",[t._v("schemaPath")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"query-building"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#query-building"}},[t._v("#")]),t._v(" Query building")]),t._v(" "),a("p",[t._v("Once the boilerplate code is generated, you can start building queries. For each "),a("em",[t._v("type")]),t._v(" in your schema, a corresponding Scala object has been created. For each "),a("em",[t._v("field")]),t._v(" in your schema, a corresponding Scala function has been created.")]),t._v(" "),a("p",[t._v("For example, given the following schema:")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("nicknames")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token scalar"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("origin")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Origin")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Your generated code will have the following:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Character "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" nicknames"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" origin"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("A "),a("code",[t._v("SelectionBuilder[Origin, A]")]),t._v(" is a selection from a parent type "),a("code",[t._v("Origin")]),t._v(" that returns a result of type "),a("code",[t._v("A")]),t._v(". In this example, "),a("code",[t._v("name")]),t._v(" is a selection from a "),a("code",[t._v("Character")]),t._v(" that returns a "),a("code",[t._v("String")]),t._v(".")]),t._v(" "),a("p",[t._v("You can combine multiple selections using the "),a("code",[t._v("~")]),t._v(" operator. The new result type will be a tuple from the 2 combined result types. Note that you can only combine selections that have the same origin.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" selection"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nicknames\n")])])]),a("p",[t._v("If you combine multiple fields, it is more convenient to have a case class to represent your data (to avoid seeing nested tuples). You can use "),a("code",[t._v("mapN")]),t._v(" to map a nested tuple to a case class.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" nickname"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" origin"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" character"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nicknames "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("mapN"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("Fields that return an object type will require an inner selection, which is another "),a("code",[t._v("SelectionBuilder")]),t._v(". Let's consider the following "),a("code",[t._v("Query")]),t._v(" type.")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Query")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("characters")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("When calling "),a("code",[t._v("characters")]),t._v(", we need to provide a "),a("code",[t._v("SelectionBuilder[Character, ?]")]),t._v(" to indicate which fields to select on the returned "),a("code",[t._v("Character")]),t._v(".")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("RootQuery"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("characters "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nicknames "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("~")]),t._v(" Character"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("mapN"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Or if we reuse the "),a("code",[t._v("character")]),t._v(" selection we just created:")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("RootQuery"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("characters "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n character\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Because this is Scala code, you can easily reuse a selection in multiple places without having to worry about GraphQL fragments. The Scala compiler will also make sure that you only combine fields that make sense.")]),t._v(" "),a("p",[t._v("When a field requires an argument, the helper method for the field will require one as well. Let's enrich our query:")]),t._v(" "),a("div",{staticClass:"language-graphql extra-class"},[a("pre",{pre:!0,attrs:{class:"language-graphql"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Query")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("characters")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("origin")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Origin")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Character")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("You now need to provide an "),a("code",[t._v("Origin")]),t._v(" when calling "),a("code",[t._v("characters")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" SelectionBuilder"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("RootQuery"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n Query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("characters"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("Origin"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("MARS"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n character\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h2",{attrs:{id:"request-execution"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#request-execution"}},[t._v("#")]),t._v(" Request execution")]),t._v(" "),a("p",[t._v("Once your query or mutation is created, it is time to execute it. To do that, you can transform your "),a("code",[t._v("SelectionBuilder")]),t._v(" into an "),a("code",[t._v("sttp")]),t._v(" request by calling "),a("code",[t._v(".toRequest")]),t._v(".")]),t._v(" "),a("p",[t._v("This function takes the URL of your GraphQL server and some options:")]),t._v(" "),a("ul",[a("li",[t._v("a boolean "),a("code",[t._v("useVariables")]),t._v(" that determines if arguments should be using variables or not (default: false)")]),t._v(" "),a("li",[t._v("an optional string "),a("code",[t._v("queryName")]),t._v(" if you want to name your query (default: no name)")]),t._v(" "),a("li",[t._v("a boolean "),a("code",[t._v("dropNullInputValues")]),t._v(" that determines if null fields from input objects should be dropped (default: false)")])]),t._v(" "),a("p",[t._v("You can then simply run the "),a("code",[t._v("sttp")]),t._v(" request with the backend of your choice. See the "),a("a",{attrs:{href:"https://sttp.readthedocs.io/en/latest/",target:"_blank",rel:"noopener noreferrer"}},[t._v("sttp docs"),a("OutboundLink")],1),t._v(" if you are not familiar with it.")]),t._v(" "),a("p",[t._v("Here is an example using the "),a("code",[t._v("AsyncHttpClient")]),t._v(" backend for "),a("code",[t._v("ZIO")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("client3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("sttp"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("client3"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("asynchttpclient"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("zio"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("AsyncHttpClientZioBackend\n\nAsyncHttpClientZioBackend"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("flatMap "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" backend "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" serverUrl "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string-interpolation"}},[a("span",{pre:!0,attrs:{class:"token id function"}},[t._v("uri")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://localhost:8088/api/graphql"')])]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" result"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Task"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("List"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CharacterView"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n query"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toRequest"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("serverUrl"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("send"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("_"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("absolve\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("As a result, we get a ZIO "),a("code",[t._v("Task")]),t._v(" whose return type is the same as our "),a("code",[t._v("SelectionBuilder")]),t._v(". The sttp request does not only contain the request to send, but also takes care of parsing the response into the expected type.")]),t._v(" "),a("p",[t._v("The "),a("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/examples/",target:"_blank",rel:"noopener noreferrer"}},[t._v("examples"),a("OutboundLink")],1),t._v(" project contains a runnable sample code that queries the example GraphQL backend.")]),t._v(" "),a("div",{staticClass:"custom-block warning"},[a("p",{staticClass:"custom-block-title"},[t._v("Limitations")]),t._v(" "),a("p",[t._v("Only Queries and Mutations are supported as sttp requests.\nSubscriptions are supported in the laminext module, and this code can easily be adapted to other frameworks (the relevant code is only a few lines long).")]),t._v(" "),a("p",[t._v("Type extensions are not supported by the codegen tool.")])])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/40.e6d4961b.js b/docs/assets/js/40.fb533a9a.js similarity index 99% rename from docs/assets/js/40.e6d4961b.js rename to docs/assets/js/40.fb533a9a.js index 38868bec47..9fad5e1182 100644 --- a/docs/assets/js/40.e6d4961b.js +++ b/docs/assets/js/40.fb533a9a.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{322:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"stitching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#stitching"}},[t._v("#")]),t._v(" Stitching")]),t._v(" "),s("p",[s("strong",[t._v("Stitching")]),t._v(" is a part of "),s("code",[t._v("caliban-tools")]),t._v(" which can be used to use parts of another GraphQL API from an API you're building in situations where using Apollo federation isn't an option. You can also use it to fully subsume and proxy another GraphQL schema.")]),t._v(" "),s("p",[t._v("In general, Federation should be your preferred choice.")]),t._v(" "),s("p",[t._v("You should also be careful when using stitching since it's very easy to pull in large parts of an external schema's types and structure into your API. This can make it error prone since the likelihood that you'll get type clashes between your API and the API you're stitching in quickly increases.")]),t._v(" "),s("h2",{attrs:{id:"dependencies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dependencies"}},[t._v("#")]),t._v(" Dependencies")]),t._v(" "),s("p",[t._v("In order to use stitching, add "),s("code",[t._v("caliban-tools")]),t._v(" to your dependencies:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tools"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),s("h2",{attrs:{id:"stitching-in-action"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#stitching-in-action"}},[t._v("#")]),t._v(" Stitching in Action")]),t._v(" "),s("p",[t._v("Let's start out by defining our API. We'll have "),s("code",[t._v("AppUser")]),t._v(" profiles, that has a linked "),s("code",[t._v("featuredRepository")]),t._v(". For the "),s("code",[t._v("featuredRepository")]),t._v(", we want to leverage "),s("a",{attrs:{href:"https://docs.github.com/en/graphql",target:"_blank",rel:"noopener noreferrer"}},[t._v("Github's GraphQL API"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("div",{staticClass:"language-scala mdoc:silent extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("ArgBuilder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" StitchingExample "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" GenericSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" AppUser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" featuredRepository"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("owner"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" GetUserQuery"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" repository"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Queries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n GetUser"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" GetUserQuery "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" UIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("AppUser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" GraphQL"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n RootResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Queries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n GetUser "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" query "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n Random"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextUUID"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("uuid "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n AppUser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" uuid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n featuredRepository "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Now let's integrate with the Github API!")]),t._v(" "),s("p",[t._v("In order to do this we're going to do a couple of things:")]),t._v(" "),s("ol",[s("li",[t._v("Load the introspection schema from Github's API")]),t._v(" "),s("li",[t._v("Parse the introspected schema into a "),s("code",[t._v("caliban.introspection.adt.__Schema")])]),t._v(" "),s("li",[t._v("Use the parsed schema to generate an "),s("code",[t._v("implicit Schema[R, A]")]),t._v(" for the entities we're stitching. This effectively replaces our own schema with one from Github.")]),t._v(" "),s("li",[t._v("Teach our implicit schema how to map our local resolver to a query that can be resolved remotely by calling Github's API.")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" GITHUB_API "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.github.com/graphql"')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n sttpClient "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("environment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("SttpClient"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1")]),t._v("\n schemaLoader "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" SchemaLoader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromIntrospection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" None"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n schema "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" schemaLoader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("load\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2")]),t._v("\n remoteSchema "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromOption"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RemoteSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseRemoteSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n remoteSchemaResolvers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RemoteSchemaResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("remoteSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" githubProfileSchema"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n remoteSchemaResolvers\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("remoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Here we need to translate our local `Repository` case class into")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a top-level query which can be issued towards Github's API.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// We do this by accepting a `caliban.execution.Field`, representing")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// all the selected fields for a repository and map that to the")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// top-level `repository` query in the Github API.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This means the final query will end up looking something like this:")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// query {")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// repository(owner: r.args.owner, name: r.args.name) {")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// . ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ResolveRequest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("field"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n arguments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"owner"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("owner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromUrl"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("provide"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sttpClient"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("However, when running this we will experience failing requests due to "),s("code",[t._v("401 Unauthorized")]),t._v(". This is because all queries to Github's API requires authorization to be provided. In order to fix this, we need to add authorization to both the introspection query as well as our remote resolver. We also need a config module that can provide us with a Github token based on the value of "),s("code",[t._v("GITHUB_TOKEN")]),t._v(" in our environment.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("githubToken"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Configuration "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" fromEnvironment "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n githubToken "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" read"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"GITHUB_TOKEN"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("githubToken"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toLayer\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" read"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Task"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Task"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("effect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n sys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("We can now update the introspection query to use our token:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n config "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("environment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Has"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n schemaLoader "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" SchemaLoader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromIntrospection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Authorization"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bearer ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("githubToken")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n")])])]),s("p",[t._v("as well as update our resolver to authorize our request.")]),t._v(" "),s("p",[t._v("In order to do this, we can use "),s("code",[t._v("RemoteResolver[R, E, A, B]")]),t._v(" which lets us compose resolution steps via "),s("code",[t._v(">>>")]),t._v(".")]),t._v(" "),s("p",[t._v("In order to make this code easier, we can extract the mechanics around sending the actual request:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" apiRequest "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toQuery "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("request"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromFunctionM"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" HttpRequest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n config "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("service"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Authorization"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bearer ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("githubToken")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("execute "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("unwrap\n")])])]),s("p",[t._v("And now we can use our new "),s("code",[t._v("apiRequest")]),t._v(" when resolving our "),s("code",[t._v("Schema[ZEnv, Repository]")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" githubProfileSchema"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n remoteSchemaResolvers\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("remoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ResolveRequest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("field"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n arguments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"owner"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("owner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" apiRequest\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("provide"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sttpClient "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v(" config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("All that's left to do is to hook up to an HTTP server and configure a Github API token. And now you have an API that can handle queries such as these:")]),t._v(" "),s("div",{staticClass:"language-graphql extra-class"},[s("pre",{pre:!0,attrs:{class:"language-graphql"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("query")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property-query"}},[t._v("GetUser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ghostdogpr"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("repository")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("id")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("featuredRepository")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property-query"}},[t._v("pullRequests")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("states")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OPEN")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("first")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("edges")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("node")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("title")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("author")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("login")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("See the "),s("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/examples/src/main/scala/example/stitching",target:"_blank",rel:"noopener noreferrer"}},[t._v("examples directory"),s("OutboundLink")],1),t._v(" for a full example.")]),t._v(" "),s("h2",{attrs:{id:"things-not-yet-supported"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#things-not-yet-supported"}},[t._v("#")]),t._v(" Things not yet supported")]),t._v(" "),s("ul",[s("li",[t._v("Type renaming.")]),t._v(" "),s("li",[t._v("Type conflict resolution strategies.")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{321:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"stitching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#stitching"}},[t._v("#")]),t._v(" Stitching")]),t._v(" "),s("p",[s("strong",[t._v("Stitching")]),t._v(" is a part of "),s("code",[t._v("caliban-tools")]),t._v(" which can be used to use parts of another GraphQL API from an API you're building in situations where using Apollo federation isn't an option. You can also use it to fully subsume and proxy another GraphQL schema.")]),t._v(" "),s("p",[t._v("In general, Federation should be your preferred choice.")]),t._v(" "),s("p",[t._v("You should also be careful when using stitching since it's very easy to pull in large parts of an external schema's types and structure into your API. This can make it error prone since the likelihood that you'll get type clashes between your API and the API you're stitching in quickly increases.")]),t._v(" "),s("h2",{attrs:{id:"dependencies"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dependencies"}},[t._v("#")]),t._v(" Dependencies")]),t._v(" "),s("p",[t._v("In order to use stitching, add "),s("code",[t._v("caliban-tools")]),t._v(" to your dependencies:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tools"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])]),s("h2",{attrs:{id:"stitching-in-action"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#stitching-in-action"}},[t._v("#")]),t._v(" Stitching in Action")]),t._v(" "),s("p",[t._v("Let's start out by defining our API. We'll have "),s("code",[t._v("AppUser")]),t._v(" profiles, that has a linked "),s("code",[t._v("featuredRepository")]),t._v(". For the "),s("code",[t._v("featuredRepository")]),t._v(", we want to leverage "),s("a",{attrs:{href:"https://docs.github.com/en/graphql",target:"_blank",rel:"noopener noreferrer"}},[t._v("Github's GraphQL API"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("div",{staticClass:"language-scala mdoc:silent extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("ArgBuilder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auto"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("_\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("zio"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("_\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" StitchingExample "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" GenericSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" AppUser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" featuredRepository"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("owner"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" GetUserQuery"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" repository"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Queries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n GetUser"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" GetUserQuery "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v(" UIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("AppUser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" GraphQL"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" graphQL"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n RootResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Queries"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n GetUser "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" query "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n Random"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("nextUUID"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("uuid "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n AppUser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" uuid"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toString"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n featuredRepository "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" query"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Now let's integrate with the Github API!")]),t._v(" "),s("p",[t._v("In order to do this we're going to do a couple of things:")]),t._v(" "),s("ol",[s("li",[t._v("Load the introspection schema from Github's API")]),t._v(" "),s("li",[t._v("Parse the introspected schema into a "),s("code",[t._v("caliban.introspection.adt.__Schema")])]),t._v(" "),s("li",[t._v("Use the parsed schema to generate an "),s("code",[t._v("implicit Schema[R, A]")]),t._v(" for the entities we're stitching. This effectively replaces our own schema with one from Github.")]),t._v(" "),s("li",[t._v("Teach our implicit schema how to map our local resolver to a query that can be resolved remotely by calling Github's API.")])]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" GITHUB_API "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://api.github.com/graphql"')]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n sttpClient "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("environment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("SttpClient"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 1")]),t._v("\n schemaLoader "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" SchemaLoader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromIntrospection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" None"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n schema "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" schemaLoader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("load\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 2")]),t._v("\n remoteSchema "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromOption"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("RemoteSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("parseRemoteSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n remoteSchemaResolvers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" RemoteSchemaResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("remoteSchema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" githubProfileSchema"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n remoteSchemaResolvers\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("remoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Here we need to translate our local `Repository` case class into")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a top-level query which can be issued towards Github's API.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// We do this by accepting a `caliban.execution.Field`, representing")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// all the selected fields for a repository and map that to the")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// top-level `repository` query in the Github API.")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// This means the final query will end up looking something like this:")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// query {")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// repository(owner: r.args.owner, name: r.args.name) {")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// . ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ResolveRequest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("field"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n arguments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"owner"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("owner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromUrl"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("provide"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sttpClient"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("However, when running this we will experience failing requests due to "),s("code",[t._v("401 Unauthorized")]),t._v(". This is because all queries to Github's API requires authorization to be provided. In order to fix this, we need to add authorization to both the introspection query as well as our remote resolver. We also need a config module that can provide us with a Github token based on the value of "),s("code",[t._v("GITHUB_TOKEN")]),t._v(" in our environment.")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("case")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("githubToken"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("object")]),t._v(" Configuration "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" fromEnvironment "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n githubToken "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" read"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"GITHUB_TOKEN"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("githubToken"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toLayer\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("private")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" read"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Task"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Task"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("effect"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n sys"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("We can now update the introspection query to use our token:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" api "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n config "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("environment"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Has"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n schemaLoader "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" SchemaLoader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromIntrospection"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n Some"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n List"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n Options"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Authorization"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bearer ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("get"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("githubToken")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v("\n")])])]),s("p",[t._v("as well as update our resolver to authorize our request.")]),t._v(" "),s("p",[t._v("In order to do this, we can use "),s("code",[t._v("RemoteResolver[R, E, A, B]")]),t._v(" which lets us compose resolution steps via "),s("code",[t._v(">>>")]),t._v(".")]),t._v(" "),s("p",[t._v("In order to make this code easier, we can extract the mechanics around sending the actual request:")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" apiRequest "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("toQuery "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("request"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("GITHUB_API"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromFunctionM"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" HttpRequest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n config "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("<-")]),t._v(" ZIO"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("service"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Configuration"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("header"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Authorization"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-interpolation"}},[s("span",{pre:!0,attrs:{class:"token id function"}},[t._v("s")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Bearer ')]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("${")]),s("span",{pre:!0,attrs:{class:"token expression"}},[t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("githubToken")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("execute "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("unwrap\n")])])]),s("p",[t._v("And now we can use our new "),s("code",[t._v("apiRequest")]),t._v(" when resolving our "),s("code",[t._v("Schema[ZEnv, Repository]")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-scala extra-class"},[s("pre",{pre:!0,attrs:{class:"language-scala"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("implicit")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" githubProfileSchema"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("\n remoteSchemaResolvers\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("remoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n RemoteResolver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("fromFunction"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" ResolveRequest"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Repository"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("=>")]),t._v("\n r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("field"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("copy"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"repository"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n arguments "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Map"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"owner"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("owner"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("->")]),t._v(" Value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StringValue"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">>>")]),t._v(" apiRequest\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("provide"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("sttpClient "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("++")]),t._v(" config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("All that's left to do is to hook up to an HTTP server and configure a Github API token. And now you have an API that can handle queries such as these:")]),t._v(" "),s("div",{staticClass:"language-graphql extra-class"},[s("pre",{pre:!0,attrs:{class:"language-graphql"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("query")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property-query"}},[t._v("GetUser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ghostdogpr"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("repository")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("id")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("featuredRepository")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property-query"}},[t._v("pullRequests")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("states")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OPEN")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("first")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("edges")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("node")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("title")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token object"}},[t._v("author")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v("login")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("See the "),s("a",{attrs:{href:"https://github.com/ghostdogpr/caliban/tree/series/2.x/examples/src/main/scala/example/stitching",target:"_blank",rel:"noopener noreferrer"}},[t._v("examples directory"),s("OutboundLink")],1),t._v(" for a full example.")]),t._v(" "),s("h2",{attrs:{id:"things-not-yet-supported"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#things-not-yet-supported"}},[t._v("#")]),t._v(" Things not yet supported")]),t._v(" "),s("ul",[s("li",[t._v("Type renaming.")]),t._v(" "),s("li",[t._v("Type conflict resolution strategies.")])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/41.6ae7d8e9.js b/docs/assets/js/41.bccfe839.js similarity index 96% rename from docs/assets/js/41.6ae7d8e9.js rename to docs/assets/js/41.bccfe839.js index 61841638e2..b22ffe383e 100644 --- a/docs/assets/js/41.6ae7d8e9.js +++ b/docs/assets/js/41.bccfe839.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{323:function(t,e,a){"use strict";a.r(e);var s=a(14),o=Object(s.a)({},(function(){var t=this,e=t._self._c;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",[t._v("Caliban comes with a module called "),e("code",[t._v("caliban-tools")]),t._v(" that exposes some useful features:")]),t._v(" "),e("ul",[e("li",[t._v("all the code generation features from "),e("code",[t._v("caliban-codegen-sbt")]),t._v(", so that you can use them without sbt: see "),e("code",[t._v("caliban.tools.Codegen")]),t._v(".")]),t._v(" "),e("li",[t._v("a client for GraphQL introspection: see "),e("code",[t._v("caliban.tools.IntrospectionClient")]),t._v(".")]),t._v(" "),e("li",[t._v("utilities for "),e("RouterLink",{attrs:{to:"/docs/stitching.html"}},[t._v("stitching GraphQL schemas")]),t._v(".")],1),t._v(" "),e("li",[t._v("a way to "),e("RouterLink",{attrs:{to:"/docs/schema-comparison.html"}},[t._v("compare GraphQL schemas")]),t._v(", whether they come from Caliban or a remote server.")],1)]),t._v(" "),e("h2",{attrs:{id:"dependency"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dependency"}},[t._v("#")]),t._v(" Dependency")]),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 string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tools"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{322:function(t,e,a){"use strict";a.r(e);var s=a(14),o=Object(s.a)({},(function(){var t=this,e=t._self._c;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",[t._v("Caliban comes with a module called "),e("code",[t._v("caliban-tools")]),t._v(" that exposes some useful features:")]),t._v(" "),e("ul",[e("li",[t._v("all the code generation features from "),e("code",[t._v("caliban-codegen-sbt")]),t._v(", so that you can use them without sbt: see "),e("code",[t._v("caliban.tools.Codegen")]),t._v(".")]),t._v(" "),e("li",[t._v("a client for GraphQL introspection: see "),e("code",[t._v("caliban.tools.IntrospectionClient")]),t._v(".")]),t._v(" "),e("li",[t._v("utilities for "),e("RouterLink",{attrs:{to:"/docs/stitching.html"}},[t._v("stitching GraphQL schemas")]),t._v(".")],1),t._v(" "),e("li",[t._v("a way to "),e("RouterLink",{attrs:{to:"/docs/schema-comparison.html"}},[t._v("compare GraphQL schemas")]),t._v(", whether they come from Caliban or a remote server.")],1)]),t._v(" "),e("h2",{attrs:{id:"dependency"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dependency"}},[t._v("#")]),t._v(" Dependency")]),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 string"}},[t._v('"com.github.ghostdogpr"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"caliban-tools"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("%")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.4.3"')]),t._v("\n")])])])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/42.d2292bd5.js b/docs/assets/js/42.99036692.js similarity index 97% rename from docs/assets/js/42.d2292bd5.js rename to docs/assets/js/42.99036692.js index 6583cefab1..4c1a8fcb61 100644 --- a/docs/assets/js/42.d2292bd5.js +++ b/docs/assets/js/42.99036692.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{321:function(t,a,s){"use strict";s.r(a);var e=s(14),n=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"validation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#validation"}},[t._v("#")]),t._v(" Validation")]),t._v(" "),a("p",[t._v("Caliban provides a little macro called "),a("code",[t._v("gqldoc")]),t._v(" that can check at "),a("strong",[t._v("compile-time")]),t._v(" that a GraphQL query (a "),a("em",[t._v("document")]),t._v(" to be exact) has valid syntax.")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Macros"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("gqldoc\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" gqldoc"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n query test {\n amos: character(name: "Amos Burton") {\n name\n }\n }"""')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("At "),a("strong",[t._v("runtime")]),t._v(", it is possible to validate a query against your schema by calling the method "),a("code",[t._v("check")]),t._v(" on your API.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" check"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CalibanError"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),a("p",[t._v("It is also possible to skip validation when executing a query by passing "),a("code",[t._v("Configurator.setSkipValidation(true)")]),t._v(" to the "),a("code",[t._v("configure")]),t._v(" function of your http/ws interpreter. This will slightly improve performance.")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{323:function(t,a,s){"use strict";s.r(a);var e=s(14),n=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"validation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#validation"}},[t._v("#")]),t._v(" Validation")]),t._v(" "),a("p",[t._v("Caliban provides a little macro called "),a("code",[t._v("gqldoc")]),t._v(" that can check at "),a("strong",[t._v("compile-time")]),t._v(" that a GraphQL query (a "),a("em",[t._v("document")]),t._v(" to be exact) has valid syntax.")]),t._v(" "),a("div",{staticClass:"language-scala mdoc:silent extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token namespace"}},[t._v("caliban"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")])]),t._v("Macros"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("gqldoc\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("val")]),t._v(" query "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" gqldoc"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token triple-quoted-string string"}},[t._v('"""\n query test {\n amos: character(name: "Amos Burton") {\n name\n }\n }"""')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("At "),a("strong",[t._v("runtime")]),t._v(", it is possible to validate a query against your schema by calling the method "),a("code",[t._v("check")]),t._v(" on your API.")]),t._v(" "),a("div",{staticClass:"language-scala extra-class"},[a("pre",{pre:!0,attrs:{class:"language-scala"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" check"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("query"),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("String")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" IO"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("CalibanError"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("Unit")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),a("p",[t._v("It is also possible to skip validation when executing a query by passing "),a("code",[t._v("Configurator.setSkipValidation(true)")]),t._v(" to the "),a("code",[t._v("configure")]),t._v(" function of your http/ws interpreter. This will slightly improve performance.")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/docs/assets/js/app.93d4a129.js b/docs/assets/js/app.8f3a58d5.js similarity index 87% rename from docs/assets/js/app.93d4a129.js rename to docs/assets/js/app.8f3a58d5.js index 0a72a57d30..1947187538 100644 --- a/docs/assets/js/app.93d4a129.js +++ b/docs/assets/js/app.8f3a58d5.js @@ -1,4 +1,4 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],[]]);!function(t){function e(e){for(var r,a,s=e[0],c=e[1],u=e[2],f=0,p=[];f
'};function o(t,e,n){return tn?n:t}function i(t){return 100*(-1+t)}n.configure=function(t){var e,n;for(e in t)void 0!==(n=t[e])&&t.hasOwnProperty(e)&&(r[e]=n);return this},n.status=null,n.set=function(t){var e=n.isStarted();t=o(t,r.minimum,1),n.status=1===t?null:t;var c=n.render(!e),u=c.querySelector(r.barSelector),l=r.speed,f=r.easing;return c.offsetWidth,a((function(e){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,function(t,e,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+i(t)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+i(t)+"%,0)"}:{"margin-left":i(t)+"%"}).transition="all "+e+"ms "+n,o}(t,l,f)),1===t?(s(c,{transition:"none",opacity:1}),c.offsetWidth,setTimeout((function(){s(c,{transition:"all "+l+"ms linear",opacity:0}),setTimeout((function(){n.remove(),e()}),l)}),l)):setTimeout(e,l)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var t=function(){setTimeout((function(){n.status&&(n.trickle(),t())}),r.trickleSpeed)};return r.trickle&&t(),this},n.done=function(t){return t||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(t){var e=n.status;return e?("number"!=typeof t&&(t=(1-e)*o(Math.random()*e,.1,.95)),e=o(e+t,0,.994),n.set(e)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},t=0,e=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===e&&n.start(),t++,e++,r.always((function(){0==--e?(t=0,n.done()):n.set((t-e)/t)})),this):this},n.render=function(t){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var e=document.createElement("div");e.id="nprogress",e.innerHTML=r.template;var o,a=e.querySelector(r.barSelector),c=t?"-100":i(n.status||0),l=document.querySelector(r.parent);return s(a,{transition:"all 0 linear",transform:"translate3d("+c+"%,0,0)"}),r.showSpinner||(o=e.querySelector(r.spinnerSelector))&&p(o),l!=document.body&&u(l,"nprogress-custom-parent"),l.appendChild(e),e},n.remove=function(){l(document.documentElement,"nprogress-busy"),l(document.querySelector(r.parent),"nprogress-custom-parent");var t=document.getElementById("nprogress");t&&p(t)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var t=document.body.style,e="WebkitTransform"in t?"Webkit":"MozTransform"in t?"Moz":"msTransform"in t?"ms":"OTransform"in t?"O":"";return e+"Perspective"in t?"translate3d":e+"Transform"in t?"translate":"margin"};var a=function(){var t=[];function e(){var n=t.shift();n&&n(e)}return function(n){t.push(n),1==t.length&&e()}}(),s=function(){var t=["Webkit","O","Moz","ms"],e={};function n(n){return n=n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(t,e){return e.toUpperCase()})),e[n]||(e[n]=function(e){var n=document.body.style;if(e in n)return e;for(var r,o=t.length,i=e.charAt(0).toUpperCase()+e.slice(1);o--;)if((r=t[o]+i)in n)return r;return e}(n))}function r(t,e,r){e=n(e),t.style[e]=r}return function(t,e){var n,o,i=arguments;if(2==i.length)for(n in e)void 0!==(o=e[n])&&e.hasOwnProperty(n)&&r(t,n,o);else r(t,i[1],i[2])}}();function c(t,e){return("string"==typeof t?t:f(t)).indexOf(" "+e+" ")>=0}function u(t,e){var n=f(t),r=n+e;c(n,e)||(t.className=r.substring(1))}function l(t,e){var n,r=f(t);c(t,e)&&(n=r.replace(" "+e+" "," "),t.className=n.substring(1,n.length-1))}function f(t){return(" "+(t.className||"")+" ").replace(/\s+/gi," ")}function p(t){t&&t.parentNode&&t.parentNode.removeChild(t)}return n})?r.call(e,n,e,t):r)||(t.exports=o)},function(t,e,n){"use strict";var r=n(1),o=n(45).f,i=n(12),a=n(92),s=n(32),c=n(61),u=n(120);t.exports=function(t,e){var n,l,f,p,d,h=t.target,v=t.global,m=t.stat;if(n=v?r:m?r[h]||s(h,{}):(r[h]||{}).prototype)for(l in e){if(p=e[l],f=t.dontCallGetSet?(d=o(n,l))&&d.value:n[l],!u(v?l:h+(m?".":"#")+l,t.forced)&&void 0!==f){if(typeof p==typeof f)continue;c(p,f)}(t.sham||f&&f.sham)&&i(p,"sham",!0),a(n,l,p,t)}}},function(t,e,n){"use strict";var r=n(25),o=Function.prototype.call;t.exports=r?o.bind(o):function(){return o.apply(o,arguments)}},function(t,e,n){"use strict";var r=n(3);t.exports=!r((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")}))},function(t,e,n){"use strict";t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e,n){"use strict";var r=n(46),o=n(47);t.exports=function(t){return r(o(t))}},function(t,e,n){"use strict";var r=n(1),o=n(0),i=function(t){return o(t)?t:void 0};t.exports=function(t,e){return arguments.length<2?i(r[t]):r[t]&&r[t][e]}},function(t,e,n){"use strict";var r=n(0),o=n(102),i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not a function")}},function(t,e,n){"use strict";var r=n(1),o=n(56),i=n(7),a=n(58),s=n(54),c=n(53),u=r.Symbol,l=o("wks"),f=c?u.for||u:u&&u.withoutSetter||a;t.exports=function(t){return i(l,t)||(l[t]=s&&i(u,t)?u[t]:f("Symbol."+t)),l[t]}},function(t,e,n){"use strict";var r=n(1),o=n(32),i=r["__core-js_shared__"]||o("__core-js_shared__",{});t.exports=i},function(t,e,n){"use strict";var r=n(1),o=Object.defineProperty;t.exports=function(t,e){try{o(r,t,{value:e,configurable:!0,writable:!0})}catch(n){r[t]=e}return e}},function(t,e,n){"use strict";var r=n(47),o=Object;t.exports=function(t){return o(r(t))}},function(t,e,n){"use strict";var r=n(8),o=String,i=TypeError;t.exports=function(t){if(r(t))return t;throw new i(o(t)+" is not an object")}},function(t,e,n){"use strict";var r=n(117);t.exports=function(t){return r(t.length)}},function(t,e,n){var r=n(143),o=n(10),i=Object.prototype,a=i.hasOwnProperty,s=i.propertyIsEnumerable,c=r(function(){return arguments}())?r:function(t){return o(t)&&a.call(t,"callee")&&!s.call(t,"callee")};t.exports=c},function(t,e,n){var r=n(9)(n(6),"Map");t.exports=r},function(t,e){t.exports=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},function(t,e,n){var r=n(163),o=n(170),i=n(172),a=n(173),s=n(174);function c(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e-1&&t%1==0&&t<=9007199254740991}},function(t,e,n){var r=n(4),o=n(43),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,a=/^\w*$/;t.exports=function(t,e){if(r(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!o(t))||(a.test(t)||!i.test(t)||null!=e&&t in Object(e))}},function(t,e,n){var r=n(11),o=n(10);t.exports=function(t){return"symbol"==typeof t||o(t)&&"[object Symbol]"==r(t)}},function(t,e){t.exports=function(t){return t}},function(t,e,n){"use strict";var r=n(5),o=n(24),i=n(98),a=n(26),s=n(27),c=n(49),u=n(7),l=n(59),f=Object.getOwnPropertyDescriptor;e.f=r?f:function(t,e){if(t=s(t),e=c(e),l)try{return f(t,e)}catch(t){}if(u(t,e))return a(!o(i.f,t,e),t[e])}},function(t,e,n){"use strict";var r=n(2),o=n(3),i=n(16),a=Object,s=r("".split);t.exports=o((function(){return!a("z").propertyIsEnumerable(0)}))?function(t){return"String"===i(t)?s(t,""):a(t)}:a},function(t,e,n){"use strict";var r=n(48),o=TypeError;t.exports=function(t){if(r(t))throw new o("Can't call method on "+t);return t}},function(t,e,n){"use strict";t.exports=function(t){return null==t}},function(t,e,n){"use strict";var r=n(99),o=n(51);t.exports=function(t){var e=r(t,"string");return o(e)?e:e+""}},function(t,e,n){"use strict";var r="object"==typeof document&&document.all,o=void 0===r&&void 0!==r;t.exports={all:r,IS_HTMLDDA:o}},function(t,e,n){"use strict";var r=n(28),o=n(0),i=n(52),a=n(53),s=Object;t.exports=a?function(t){return"symbol"==typeof t}:function(t){var e=r("Symbol");return o(e)&&i(e.prototype,s(t))}},function(t,e,n){"use strict";var r=n(2);t.exports=r({}.isPrototypeOf)},function(t,e,n){"use strict";var r=n(54);t.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},function(t,e,n){"use strict";var r=n(55),o=n(3),i=n(1).String;t.exports=!!Object.getOwnPropertySymbols&&!o((function(){var t=Symbol("symbol detection");return!i(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},function(t,e,n){"use strict";var r,o,i=n(1),a=n(100),s=i.process,c=i.Deno,u=s&&s.versions||c&&c.version,l=u&&u.v8;l&&(o=(r=l.split("."))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!o&&a&&(!(r=a.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=a.match(/Chrome\/(\d+)/))&&(o=+r[1]),t.exports=o},function(t,e,n){"use strict";var r=n(57),o=n(31);(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.34.0",mode:r?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.34.0/LICENSE",source:"https://github.com/zloirock/core-js"})},function(t,e,n){"use strict";t.exports=!1},function(t,e,n){"use strict";var r=n(2),o=0,i=Math.random(),a=r(1..toString);t.exports=function(t){return"Symbol("+(void 0===t?"":t)+")_"+a(++o+i,36)}},function(t,e,n){"use strict";var r=n(5),o=n(3),i=n(104);t.exports=!r&&!o((function(){return 7!==Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(t,e,n){"use strict";t.exports={}},function(t,e,n){"use strict";var r=n(7),o=n(111),i=n(45),a=n(15);t.exports=function(t,e,n){for(var s=o(e),c=a.f,u=i.f,l=0;ll))return!1;var p=c.get(t),d=c.get(e);if(p&&d)return p==e&&d==t;var h=-1,v=!0,m=2&n?new r:void 0;for(c.set(t,e),c.set(e,t);++h-1&&t%1==0&&t=0&&Math.floor(e)===e&&isFinite(t)}function v(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||p(t)&&t.toString===f?JSON.stringify(t,null,2):String(t)}function y(t){var e=parseFloat(t);return isNaN(e)?t:e}function g(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(r,1)}}var x=Object.prototype.hasOwnProperty;function w(t,e){return x.call(t,e)}function C(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var O=/-(\w)/g,$=C((function(t){return t.replace(O,(function(t,e){return e?e.toUpperCase():""}))})),k=C((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),S=/\B([A-Z])/g,j=C((function(t){return t.replace(S,"-$1").toLowerCase()}));var E=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function P(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function A(t,e){for(var n in e)t[n]=e[n];return t}function T(t){for(var e={},n=0;n0,X=Q&&Q.indexOf("edge/")>0;Q&&Q.indexOf("android");var Y=Q&&/iphone|ipad|ipod|ios/.test(Q);Q&&/chrome\/\d+/.test(Q),Q&&/phantomjs/.test(Q);var tt,et=Q&&Q.match(/firefox\/(\d+)/),nt={}.watch,rt=!1;if(K)try{var ot={};Object.defineProperty(ot,"passive",{get:function(){rt=!0}}),window.addEventListener("test-passive",null,ot)}catch(t){}var it=function(){return void 0===tt&&(tt=!K&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=K&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function st(t){return"function"==typeof t&&/native code/.test(t.toString())}var ct,ut="undefined"!=typeof Symbol&&st(Symbol)&&"undefined"!=typeof Reflect&&st(Reflect.ownKeys);ct="undefined"!=typeof Set&&st(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var lt=null;function ft(t){void 0===t&&(t=null),t||lt&<._scope.off(),lt=t,t&&t._scope.on()}var pt=function(){function t(t,e,n,r,o,i,a,s){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),dt=function(t){void 0===t&&(t="");var e=new pt;return e.text=t,e.isComment=!0,e};function ht(t){return new pt(void 0,void 0,void 0,String(t))}function vt(t){var e=new pt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var mt=0,yt=[],gt=function(){function t(){this._pending=!1,this.id=mt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,yt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,r=e.length;n0&&(Qt((u=t(u,"".concat(n||"","_").concat(r)))[0])&&Qt(f)&&(p[l]=ht(f.text+u[0].text),u.shift()),p.push.apply(p,u)):c(u)?Qt(f)?p[l]=ht(f.text+u):""!==u&&p.push(ht(u)):Qt(u)&&Qt(f)?p[l]=ht(f.text+u.text):(s(e._isVList)&&a(u.tag)&&i(u.key)&&a(n)&&(u.key="__vlist".concat(n,"_").concat(r,"__")),p.push(u)));return p}(t):void 0}function Qt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Jt(t,e){var n,r,i,s,c=null;if(o(t)||"string"==typeof t)for(c=new Array(t.length),n=0,r=t.length;n0,s=e?!!e.$stable:!a,c=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(s&&o&&o!==r&&c===o.$key&&!a&&!o.$hasNormal)return o;for(var u in i={},e)e[u]&&"$"!==u[0]&&(i[u]=ve(t,n,u,e[u]))}else i={};for(var l in n)l in i||(i[l]=me(n,l));return e&&Object.isExtensible(e)&&(e._normalized=i),H(i,"$stable",s),H(i,"$key",c),H(i,"$hasNormal",a),i}function ve(t,e,n,r){var i=function(){var e=lt;ft(t);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==typeof n&&!o(n)?[n]:Kt(n))&&n[0];return ft(e),n&&(!i||1===n.length&&i.isComment&&!de(i))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:i,enumerable:!0,configurable:!0}),i}function me(t,e){return function(){return t[e]}}function ye(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),ge(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ge(t._listenersProxy={},t.$listeners,r,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||_e(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:E(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return Ft(t,e,n)}))}}}function ge(t,e,n,r,o){var i=!1;for(var a in e)a in t?e[a]!==n[a]&&(i=!0):(i=!0,be(t,a,r,o));for(var a in t)a in e||(i=!0,delete t[a]);return i}function be(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function _e(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var xe=null;function we(t,e){return(t.__esModule||ut&&"Module"===t[Symbol.toStringTag])&&(t=t.default),l(t)?e.extend(t):t}function Ce(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(cn=function(){return un.now()})}var ln=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function fn(){var t,e;for(sn=cn(),on=!0,tn.sort(ln),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Ne(fn))}}function dn(t,e){if(t){for(var n=Object.create(null),r=ut?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(i&&!w(o,"default"))a=!1;else if(""===a||a===j(t)){var c=In(String,o.type);(c<0||s-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!d(t)&&t.test(e)}function Jn(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=a.name;s&&!e(s)&&Zn(n,i,r,o)}}}function Zn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,_(n,e)}Wn.prototype._init=function(t){var e=this;e._uid=Vn++,e._isVue=!0,e.__v_skip=!0,e._scope=new Ut(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=En(Hn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ke(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=fe(e._renderChildren,o),t.$scopedSlots=n?he(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,o){return Oe(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return Oe(t,e,n,r,o,!0)};var i=n&&n.data;At(t,"$attrs",i&&i.attrs||r,null,!0),At(t,"$listeners",e._parentListeners||r,null,!0)}(e),Ye(e,"beforeCreate",void 0,!1),function(t){var e=dn(t.$options.inject,t);e&&(St(!1),Object.keys(e).forEach((function(n){At(t,n,e[n])})),St(!0))}(e),Nn(e),function(t){var e=t.$options.provide;if(e){var n=u(e)?e.call(t):e;if(!l(n))return;for(var r=Bt(t),o=ut?Reflect.ownKeys(n):Object.keys(n),i=0;i1?P(n):n;for(var r=P(arguments,1),o='event handler for "'.concat(t,'"'),i=0,a=n.length;iparseInt(this.max)&&Zn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Zn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Jn(t,(function(t){return Qn(e,t)}))})),this.$watch("exclude",(function(e){Jn(t,(function(t){return!Qn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=Ce(t),n=e&&e.componentOptions;if(n){var r=Kn(n),o=this.include,i=this.exclude;if(o&&(!r||!Qn(o,r))||i&&r&&Qn(i,r))return e;var a=this.cache,s=this.keys,c=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[c]?(e.componentInstance=a[c].componentInstance,_(s,c),s.push(c)):(this.vnodeToCache=e,this.keyToCache=c),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return B}};Object.defineProperty(t,"config",e),t.util={warn:wn,extend:A,mergeOptions:En,defineReactive:At},t.set=Tt,t.delete=Lt,t.nextTick=Ne,t.observable=function(t){return Pt(t),t},t.options=Object.create(null),z.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,A(t.options.components,Yn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=P(arguments,1);return n.unshift(this),u(t.install)?t.install.apply(t,n):u(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=En(this.options,t),this}}(t),Gn(t),function(t){z.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&p(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&u(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Wn),Object.defineProperty(Wn.prototype,"$isServer",{get:it}),Object.defineProperty(Wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Wn,"FunctionalRenderContext",{value:hn}),Wn.version="2.7.15";var tr=g("style,class"),er=g("input,textarea,option,select,progress"),nr=g("contenteditable,draggable,spellcheck"),rr=g("events,caret,typing,plaintext-only"),or=g("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ir="http://www.w3.org/1999/xlink",ar=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},sr=function(t){return ar(t)?t.slice(6,t.length):""},cr=function(t){return null==t||!1===t};function ur(t){for(var e=t.data,n=t,r=t;a(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=lr(r.data,e));for(;a(n=n.parent);)n&&n.data&&(e=lr(e,n.data));return function(t,e){if(a(t)||a(e))return fr(t,pr(e));return""}(e.staticClass,e.class)}function lr(t,e){return{staticClass:fr(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function fr(t,e){return t?e?t+" "+e:t:e||""}function pr(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?Mr(t,e,n):or(e)?cr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return cr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):ar(e)?cr(n)?t.removeAttributeNS(ir,sr(e)):t.setAttributeNS(ir,e,n):Mr(t,e,n)}function Mr(t,e,n){if(cr(n))t.removeAttribute(e);else{if(J&&!Z&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Dr={create:Rr,update:Rr};function Nr(t,e){var n=e.elm,r=e.data,o=t.data;if(!(i(r.staticClass)&&i(r.class)&&(i(o)||i(o.staticClass)&&i(o.class)))){var s=ur(e),c=n._transitionClasses;a(c)&&(s=fr(s,pr(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var Fr,zr={create:Nr,update:Nr};function Ur(t,e,n){var r=Fr;return function o(){var i=e.apply(null,arguments);null!==i&&Vr(t,o,n,r)}}var Br=Pe&&!(et&&Number(et[1])<=53);function qr(t,e,n,r){if(Br){var o=sn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}Fr.addEventListener(t,e,rt?{capture:n,passive:r}:n)}function Vr(t,e,n,r){(r||Fr).removeEventListener(t,e._wrapper||e,n)}function Hr(t,e){if(!i(t.data.on)||!i(e.data.on)){var n=e.data.on||{},r=t.data.on||{};Fr=e.elm||t.elm,function(t){if(a(t.__r)){var e=J?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Ht(n,r,qr,Vr,Ur,e.context),Fr=void 0}}var Wr,Gr={create:Hr,update:Hr,destroy:function(t){return Hr(t,Cr)}};function Kr(t,e){if(!i(t.data.domProps)||!i(e.data.domProps)){var n,r,o=e.elm,c=t.data.domProps||{},u=e.data.domProps||{};for(n in(a(u.__ob__)||s(u._v_attr_proxy))&&(u=e.data.domProps=A({},u)),c)n in u||(o[n]="");for(n in u){if(r=u[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===c[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=r;var l=i(r)?"":String(r);Qr(o,l)&&(o.value=l)}else if("innerHTML"===n&&vr(o.tagName)&&i(o.innerHTML)){(Wr=Wr||document.createElement("div")).innerHTML="".concat(r,"");for(var f=Wr.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;f.firstChild;)o.appendChild(f.firstChild)}else if(r!==c[n])try{o[n]=r}catch(t){}}}}function Qr(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,r=t._vModifiers;if(a(r)){if(r.number)return y(n)!==y(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Jr={create:Kr,update:Kr},Zr=C((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Xr(t){var e=Yr(t.style);return t.staticStyle?A(t.staticStyle,e):e}function Yr(t){return Array.isArray(t)?T(t):"string"==typeof t?Zr(t):t}var to,eo=/^--/,no=/\s*!important$/,ro=function(t,e,n){if(eo.test(e))t.style.setProperty(e,n);else if(no.test(n))t.style.setProperty(j(e),n.replace(no,""),"important");else{var r=io(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(co).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function lo(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(co).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function fo(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&A(e,po(t.name||"v")),A(e,t),e}return"string"==typeof t?po(t):void 0}}var po=C((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),ho=K&&!Z,vo="transition",mo="transitionend",yo="animation",go="animationend";ho&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(vo="WebkitTransition",mo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(yo="WebkitAnimation",go="webkitAnimationEnd"));var bo=K?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function _o(t){bo((function(){bo(t)}))}function xo(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),uo(t,e))}function wo(t,e){t._transitionClasses&&_(t._transitionClasses,e),lo(t,e)}function Co(t,e,n){var r=$o(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s="transition"===o?mo:go,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout((function(){c0&&(n="transition",l=a,f=i.length):"animation"===e?u>0&&(n="animation",l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?"transition":"animation":null)?"transition"===n?i.length:c.length:0,{type:n,timeout:l,propCount:f,hasTransform:"transition"===n&&Oo.test(r[vo+"Property"])}}function ko(t,e){for(;t.length1}function To(t,e){!0!==e.data.show&&jo(e)}var Lo=function(t){var e,n,r={},u=t.modules,l=t.nodeOps;for(e=0;eh?_(t,i(n[y+1])?null:n[y+1].elm,n,d,y,r):d>y&&w(e,f,h)}(f,v,y,n,u):a(y)?(a(t.text)&&l.setTextContent(f,""),_(f,null,y,0,y.length-1,n)):a(v)?w(v,0,v.length-1):a(t.text)&&l.setTextContent(f,""):t.text!==e.text&&l.setTextContent(f,e.text),a(h)&&a(d=h.hook)&&a(d=d.postpatch)&&d(t,e)}}}function k(t,e,n){if(s(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(M(No(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function Do(t,e){return e.every((function(e){return!M(e,t)}))}function No(t){return"_value"in t?t._value:t.value}function Fo(t){t.target.composing=!0}function zo(t){t.target.composing&&(t.target.composing=!1,Uo(t.target,"input"))}function Uo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Bo(t){return!t.componentInstance||t.data&&t.data.transition?t:Bo(t.componentInstance._vnode)}var qo={model:Ro,show:{bind:function(t,e,n){var r=e.value,o=(n=Bo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,jo(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=Bo(n)).data&&n.data.transition?(n.data.show=!0,r?jo(n,(function(){t.style.display=t.__vOriginalDisplay})):Eo(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},Vo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Ho(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ho(Ce(e.children)):t}function Wo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var r in o)e[$(r)]=o[r];return e}function Go(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Ko=function(t){return t.tag||de(t)},Qo=function(t){return"show"===t.name},Jo={name:"transition",props:Vo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Ko)).length){0;var r=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var i=Ho(o);if(!i)return o;if(this._leaving)return Go(t,o);var a="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?a+"comment":a+i.tag:c(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s=(i.data||(i.data={})).transition=Wo(this),u=this._vnode,l=Ho(u);if(i.data.directives&&i.data.directives.some(Qo)&&(i.data.show=!0),l&&l.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,l)&&!de(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=A({},s);if("out-in"===r)return this._leaving=!0,Wt(f,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Go(t,o);if("in-out"===r){if(de(i))return u;var p,d=function(){p()};Wt(s,"afterEnter",d),Wt(s,"enterCancelled",d),Wt(f,"delayLeave",(function(t){p=t}))}}return o}}},Zo=A({tag:String,moveClass:String},Vo);function Xo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Yo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ti(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate(".concat(r,"px,").concat(o,"px)"),i.transitionDuration="0s"}}delete Zo.mode;var ei={Transition:Jo,TransitionGroup:{props:Zo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Je(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Wo(this),s=0;s-1?yr[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:yr[t]=/HTMLUnknownElement/.test(e.toString())},A(Wn.options.directives,qo),A(Wn.options.components,ei),Wn.prototype.__patch__=K?Lo:L,Wn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=dt),Ye(t,"beforeMount"),r=function(){t._update(t._render(),n)},new Ve(t,r,L,{before:function(){t._isMounted&&!t._isDestroyed&&Ye(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var i=0;i=0&&(e=t.slice(r),t=t.slice(0,r));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),u=e&&e.path||"/",l=c.path?wi(c.path,u,n||o.append):u,f=function(t,e,n){void 0===e&&(e={});var r,o=n||ui;try{r=o(t||"")}catch(t){r={}}for(var i in e){var a=e[i];r[i]=Array.isArray(a)?a.map(ci):ci(a)}return r}(c.query,o.query,r&&r.options.parseQuery),p=o.hash||c.hash;return p&&"#"!==p.charAt(0)&&(p="#"+p),{_normalized:!0,path:l,query:f,hash:p}}var qi,Vi=function(){},Hi={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,s=o.href,c={},u=n.options.linkActiveClass,l=n.options.linkExactActiveClass,f=null==u?"router-link-active":u,p=null==l?"router-link-exact-active":l,d=null==this.activeClass?f:this.activeClass,h=null==this.exactActiveClass?p:this.exactActiveClass,v=a.redirectedFrom?pi(null,Bi(a.redirectedFrom),null,n):a;c[h]=yi(r,v,this.exactPath),c[d]=this.exact||this.exactPath?c[h]:function(t,e){return 0===t.path.replace(fi,"/").indexOf(e.path.replace(fi,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,v);var m=c[h]?this.ariaCurrentValue:null,y=function(t){Wi(t)&&(e.replace?n.replace(i,Vi):n.push(i,Vi))},g={click:Wi};Array.isArray(this.event)?this.event.forEach((function(t){g[t]=y})):g[this.event]=y;var b={class:c},_=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:s,route:a,navigate:y,isActive:c[d],isExactActive:c[h]});if(_){if(1===_.length)return _[0];if(_.length>1||!_.length)return 0===_.length?t():t("span",{},_)}if("a"===this.tag)b.on=g,b.attrs={href:s,"aria-current":m};else{var x=function t(e){var n;if(e)for(var r=0;r-1&&(s.params[p]=n.params[p]);return s.path=Ui(l.path,s.params),c(l,s,a)}if(s.path){s.params={};for(var d=0;d-1}function Ca(t,e){return wa(t)&&t._isRouter&&(null==e||t.type===e)}function Oa(t,e,n){var r=function(o){o>=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function $a(t){return function(e,n,r){var o=!1,i=0,a=null;ka(t,(function(t,e,n,s){if("function"==typeof t&&void 0===t.cid){o=!0,i++;var c,u=Ea((function(e){var o;((o=e).__esModule||ja&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:qi.extend(e),n.components[s]=e,--i<=0&&r()})),l=Ea((function(t){var e="Failed to resolve async component "+s+": "+t;a||(a=wa(t)?t:new Error(e),r(a))}));try{c=t(u,l)}catch(t){l(t)}if(c)if("function"==typeof c.then)c.then(u,l);else{var f=c.component;f&&"function"==typeof f.then&&f.then(u,l)}}})),o||r()}}function ka(t,e){return Sa(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Sa(t){return Array.prototype.concat.apply([],t)}var ja="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ea(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var Pa=function(t,e){this.router=t,this.base=function(t){if(!t)if(Gi){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=hi,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Aa(t,e,n,r){var o=ka(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=qi.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return Sa(r?o.reverse():o)}function Ta(t,e){if(e)return function(){return t.apply(e,arguments)}}Pa.prototype.listen=function(t){this.cb=t},Pa.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Pa.prototype.onError=function(t){this.errorCbs.push(t)},Pa.prototype.transitionTo=function(t,e,n){var r,o=this;try{r=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),e&&e(r),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(r)})))}),(function(t){n&&n(t),t&&!o.ready&&(Ca(t,ya.redirected)&&i===hi||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},Pa.prototype.confirmTransition=function(t,e,n){var r=this,o=this.current;this.pending=t;var i,a,s=function(t){!Ca(t)&&wa(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},c=t.matched.length-1,u=o.matched.length-1;if(yi(t,o)&&c===u&&t.matched[c]===o.matched[u])return this.ensureURL(),t.hash&&ia(this.router,o,t,!1),s(((a=_a(i=o,t,ya.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var l=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=ha&&n;r&&this.listeners.push(oa());var o=function(){var n=t.current,o=Ra(t.base);t.current===hi&&o===t._startLocation||t.transitionTo(o,(function(t){r&&ia(e,t,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){va(Ci(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){ma(Ci(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Ra(this.base)!==this.current.fullPath){var e=Ci(this.base+this.current.fullPath);t?va(e):ma(e)}},e.prototype.getCurrentLocation=function(){return Ra(this.base)},e}(Pa);function Ra(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(Ci(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var Ia=function(t){function e(e,n,r){t.call(this,e,n),r&&function(t){var e=Ra(t);if(!/^\/#/.test(e))return window.location.replace(Ci(t+"/#"+e)),!0}(this.base)||Ma()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=ha&&e;n&&this.listeners.push(oa());var r=function(){var e=t.current;Ma()&&t.transitionTo(Da(),(function(r){n&&ia(t.router,r,e,!0),ha||za(r.fullPath)}))},o=ha?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Fa(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){za(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Da()!==e&&(t?Fa(e):za(e))},e.prototype.getCurrentLocation=function(){return Da()},e}(Pa);function Ma(){var t=Da();return"/"===t.charAt(0)||(za("/"+t),!1)}function Da(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Na(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function Fa(t){ha?va(Na(t)):window.location.hash=t}function za(t){ha?ma(Na(t)):window.location.replace(Na(t))}var Ua=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){Ca(t,ya.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Pa),Ba=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Ji(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ha&&!1!==t.fallback,this.fallback&&(e="hash"),Gi||(e="abstract"),this.mode=e,e){case"history":this.history=new La(this,t.base);break;case"hash":this.history=new Ia(this,t.base,this.fallback);break;case"abstract":this.history=new Ua(this,t.base);break;default:0}},qa={currentRoute:{configurable:!0}};Ba.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},qa.currentRoute.get=function(){return this.history&&this.history.current},Ba.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof La||n instanceof Ia){var r=function(t){n.setupListeners(),function(t){var r=n.current,o=e.options.scrollBehavior;ha&&o&&"fullPath"in t&&ia(e,t,r,!1)}(t)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Ba.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},Ba.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},Ba.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},Ba.prototype.onReady=function(t,e){this.history.onReady(t,e)},Ba.prototype.onError=function(t){this.history.onError(t)},Ba.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},Ba.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},Ba.prototype.go=function(t){this.history.go(t)},Ba.prototype.back=function(){this.go(-1)},Ba.prototype.forward=function(){this.go(1)},Ba.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Ba.prototype.resolve=function(t,e,n){var r=Bi(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?Ci(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},Ba.prototype.getRoutes=function(){return this.matcher.getRoutes()},Ba.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Ba.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Ba.prototype,qa);var Va=Ba;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Ba.install=function t(e){if(!t.installed||qi!==e){t.installed=!0,qi=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",_i),e.component("RouterLink",Hi);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Ba.version="3.6.5",Ba.isNavigationFailure=Ca,Ba.NavigationFailureType=ya,Ba.START_LOCATION=hi,Gi&&window.Vue&&window.Vue.use(Ba);n(97);n(90),n(127);var Wa={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(13)]).then(n.bind(null,297)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(14)]).then(n.bind(null,254)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(19)]).then(n.bind(null,242)),"components/Home":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,280)),"components/NavLink":()=>n.e(21).then(n.bind(null,241)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(12)]).then(n.bind(null,265)),"components/Navbar":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,294)),"components/Page":()=>Promise.all([n.e(0),n.e(11)]).then(n.bind(null,281)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(17)]).then(n.bind(null,267)),"components/PageNav":()=>Promise.all([n.e(0),n.e(15)]).then(n.bind(null,268)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,282)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(20)]).then(n.bind(null,283)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,266)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,255)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,253)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,302)),"global-components/CodeBlock":()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,298)),"global-components/CodeGroup":()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,299)),"layouts/404":()=>n.e(7).then(n.bind(null,300)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,301)),NotFound:()=>n.e(7).then(n.bind(null,300)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,301))},Ga={"v-3c88bbf2":()=>n.e(22).then(n.bind(null,303)),"v-0decf914":()=>n.e(23).then(n.bind(null,304)),"v-c864372e":()=>n.e(25).then(n.bind(null,305)),"v-102beaee":()=>n.e(26).then(n.bind(null,306)),"v-23f0ba6e":()=>n.e(27).then(n.bind(null,307)),"v-d7e5bcfc":()=>n.e(24).then(n.bind(null,308)),"v-4419f5c9":()=>n.e(28).then(n.bind(null,309)),"v-05e5796e":()=>n.e(29).then(n.bind(null,310)),"v-6d148503":()=>n.e(30).then(n.bind(null,311)),"v-70457f72":()=>n.e(31).then(n.bind(null,312)),"v-41c3bc69":()=>n.e(32).then(n.bind(null,313)),"v-2bf9c0ae":()=>n.e(33).then(n.bind(null,314)),"v-1c00b5c9":()=>n.e(34).then(n.bind(null,315)),"v-56e4d50b":()=>n.e(35).then(n.bind(null,316)),"v-4f917bd3":()=>n.e(36).then(n.bind(null,317)),"v-87b4d6ae":()=>n.e(37).then(n.bind(null,318)),"v-7bafdcee":()=>n.e(38).then(n.bind(null,319)),"v-6abbdcee":()=>n.e(39).then(n.bind(null,320)),"v-300a59ee":()=>n.e(42).then(n.bind(null,321)),"v-ded899ca":()=>n.e(40).then(n.bind(null,322)),"v-09883f07":()=>n.e(41).then(n.bind(null,323)),"v-40b685e4":()=>n.e(43).then(n.bind(null,324)),"v-a971ed74":()=>n.e(44).then(n.bind(null,325))};function Ka(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Qa=/-(\w)/g,Ja=Ka(t=>t.replace(Qa,(t,e)=>e?e.toUpperCase():"")),Za=/\B([A-Z])/g,Xa=Ka(t=>t.replace(Za,"-$1").toLowerCase()),Ya=Ka(t=>t.charAt(0).toUpperCase()+t.slice(1));function ts(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Ya(Ja(e))):t(Ya(e))||t(Xa(e))}const es=Object.assign({},Wa,Ga),ns=t=>es[t],rs=t=>Ga[t],os=t=>Wa[t],is=t=>Wn.component(t);function as(t){return ts(rs,t)}function ss(t){return ts(os,t)}function cs(t){return ts(ns,t)}function us(t){return ts(is,t)}function ls(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!us(t)&&cs(t)){const e=await cs(t)();Wn.component(t,e.default)}}))}function fs(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var ps=n(87),ds=n.n(ps),hs=n(88),vs=n.n(hs),ms={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${vs()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=gs(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=bs(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return ds()([{name:"description",content:this.$description}],t,this.siteMeta,_s)},updateCanonicalLink(){ys(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",gs(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){bs(null,this.currentMetaTags),ys()}};function ys(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function gs(t=""){return t?``:""}function bs(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function _s(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var xs=n(89),ws={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(xs)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Cs=n(22),Os=n.n(Cs),$s=[ms,ws,{mounted(){Os.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Wn.component(t.name)||Os.a.start(),n()}),this.$router.afterEach(()=>{Os.a.done(),this.isSidebarOpen=!1})}}],ks={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return fs("layout",t),Wn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},Ss=n(14),js=Object(Ss.a)(ks,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(js,"mixins",$s);const Es=[{name:"v-3c88bbf2",path:"/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-3c88bbf2").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-0decf914",path:"/about/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-0decf914").then(n)}},{path:"/about/index.html",redirect:"/about/"},{name:"v-c864372e",path:"/docs/adapters.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-c864372e").then(n)}},{name:"v-102beaee",path:"/docs/client-codegen.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-102beaee").then(n)}},{name:"v-23f0ba6e",path:"/docs/client.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-23f0ba6e").then(n)}},{name:"v-d7e5bcfc",path:"/docs/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-d7e5bcfc").then(n)}},{path:"/docs/index.html",redirect:"/docs/"},{name:"v-4419f5c9",path:"/docs/examples.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-4419f5c9").then(n)}},{name:"v-05e5796e",path:"/docs/federation.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-05e5796e").then(n)}},{name:"v-6d148503",path:"/docs/interop.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-6d148503").then(n)}},{name:"v-70457f72",path:"/docs/introspection.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-70457f72").then(n)}},{name:"v-41c3bc69",path:"/docs/laminext.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-41c3bc69").then(n)}},{name:"v-2bf9c0ae",path:"/docs/middleware.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-2bf9c0ae").then(n)}},{name:"v-1c00b5c9",path:"/docs/optimization.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-1c00b5c9").then(n)}},{name:"v-56e4d50b",path:"/docs/relay-connections.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-56e4d50b").then(n)}},{name:"v-4f917bd3",path:"/docs/schema-comparison.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-4f917bd3").then(n)}},{name:"v-87b4d6ae",path:"/docs/schema-reporting.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-87b4d6ae").then(n)}},{name:"v-7bafdcee",path:"/docs/schema.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-7bafdcee").then(n)}},{name:"v-6abbdcee",path:"/docs/server-codegen.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-6abbdcee").then(n)}},{name:"v-300a59ee",path:"/docs/validation.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-300a59ee").then(n)}},{name:"v-ded899ca",path:"/docs/stitching.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-ded899ca").then(n)}},{name:"v-09883f07",path:"/docs/tools.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-09883f07").then(n)}},{name:"v-40b685e4",path:"/faq/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-40b685e4").then(n)}},{path:"/faq/index.html",redirect:"/faq/"},{name:"v-a971ed74",path:"/resources/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-a971ed74").then(n)}},{path:"/resources/index.html",redirect:"/resources/"},{path:"*",component:js}],Ps={title:"",description:"",base:"/caliban/",headTags:[["link",{rel:"icon",href:"/caliban/caliban.png"}]],pages:[{title:"Home",frontmatter:{home:!0,heroImage:"/caliban.svg",actionText:"Get Started →",actionLink:"/docs/",features:[{title:"Purely functional",details:"All interfaces are pure and types are referentially transparent. Schemas are type safe and derived at compile time."},{title:"Minimal boilerplate",details:"No need to manually define a schema for every type in your API. Let the compiler do the boring work."},{title:"Excellent interoperability",details:"Out-of-the-box support for major HTTP server libraries, effect types, Json libraries and more."}]},regularPath:"/",relativePath:"README.md",key:"v-3c88bbf2",path:"/"},{title:"About",frontmatter:{},regularPath:"/about/",relativePath:"about/README.md",key:"v-0decf914",path:"/about/"},{title:"Http Adapters",frontmatter:{},regularPath:"/docs/adapters.html",relativePath:"docs/adapters.md",key:"v-c864372e",path:"/docs/adapters.html",headers:[{level:2,title:"Built-in tapir adapters",slug:"built-in-tapir-adapters"},{level:2,title:"Json handling",slug:"json-handling"},{level:2,title:"Make your own adapter",slug:"make-your-own-adapter"},{level:2,title:"High-performance QuickAdapter",slug:"high-performance-quickadapter"},{level:3,title:"Usage",slug:"usage"},{level:3,title:"Customization",slug:"customization"}]},{title:"Code Generation",frontmatter:{},regularPath:"/docs/client-codegen.html",relativePath:"docs/client-codegen.md",key:"v-102beaee",path:"/docs/client-codegen.html",headers:[{level:2,title:"CalibanPlugin",slug:"calibanplugin"},{level:3,title:"From a schema file",slug:"from-a-schema-file"},{level:3,title:"From a server URL",slug:"from-a-server-url"},{level:3,title:"Generation settings",slug:"generation-settings"},{level:3,title:"Manual generation",slug:"manual-generation"},{level:2,title:"CompileTimeCalibanPlugin",slug:"compiletimecalibanplugin"},{level:3,title:"Server side configuration",slug:"server-side-configuration"},{level:3,title:"Client side configuration",slug:"client-side-configuration"},{level:3,title:"Additional information about CompileTimeCalibanPlugin",slug:"additional-information-about-compiletimecalibanplugin"}]},{title:"Getting Started",frontmatter:{},regularPath:"/docs/client.html",relativePath:"docs/client.md",key:"v-23f0ba6e",path:"/docs/client.html",headers:[{level:2,title:"Dependencies",slug:"dependencies"},{level:2,title:"Code generation",slug:"code-generation"},{level:2,title:"Query building",slug:"query-building"},{level:2,title:"Request execution",slug:"request-execution"}]},{title:"Getting Started",frontmatter:{},regularPath:"/docs/",relativePath:"docs/README.md",key:"v-d7e5bcfc",path:"/docs/",headers:[{level:2,title:"A simple example",slug:"a-simple-example"},{level:2,title:"Mutations",slug:"mutations"},{level:2,title:"Subscriptions",slug:"subscriptions"},{level:2,title:"Serving over HTTP",slug:"serving-over-http"},{level:2,title:"Interop with 3rd-party libraries",slug:"interop-with-3rd-party-libraries"}]},{title:"Examples",frontmatter:{},regularPath:"/docs/examples.html",relativePath:"docs/examples.md",key:"v-4419f5c9",path:"/docs/examples.html"},{title:"Federation",frontmatter:{},regularPath:"/docs/federation.html",relativePath:"docs/federation.md",key:"v-05e5796e",path:"/docs/federation.html",headers:[{level:2,title:"Dependencies",slug:"dependencies"},{level:2,title:"Federating",slug:"federating"},{level:2,title:"Tracing",slug:"tracing"},{level:2,title:"Federation V2",slug:"federation-v2"},{level:3,title:"Customizing Federation",slug:"customizing-federation"}]},{title:"Interop",frontmatter:{},regularPath:"/docs/interop.html",relativePath:"docs/interop.md",key:"v-6d148503",path:"/docs/interop.html",headers:[{level:2,title:"Cats Effect",slug:"cats-effect"},{level:2,title:"Monix (only with cats-effect 2.x)",slug:"monix-only-with-cats-effect-2-x"},{level:2,title:"Tapir",slug:"tapir"},{level:3,title:"GraphQL restrictions",slug:"graphql-restrictions"}]},{title:"Introspection",frontmatter:{},regularPath:"/docs/introspection.html",relativePath:"docs/introspection.md",key:"v-70457f72",path:"/docs/introspection.html"},{title:"Laminext Integration",frontmatter:{},regularPath:"/docs/laminext.html",relativePath:"docs/laminext.md",key:"v-41c3bc69",path:"/docs/laminext.html"},{title:"Middleware",frontmatter:{},regularPath:"/docs/middleware.html",relativePath:"docs/middleware.md",key:"v-2bf9c0ae",path:"/docs/middleware.html",headers:[{level:2,title:"Wrapper types",slug:"wrapper-types"},{level:2,title:"Pre-defined wrappers",slug:"pre-defined-wrappers"},{level:2,title:"Wrapping the interpreter",slug:"wrapping-the-interpreter"},{level:2,title:"Customizing error responses",slug:"customizing-error-responses"},{level:2,title:"Wrapping the GraphQL",slug:"wrapping-the-graphql"},{level:2,title:"Cost Estimation",slug:"cost-estimation"},{level:2,title:"OpenTelemetry Tracing",slug:"opentelemetry-tracing"}]},{title:"Query optimization",frontmatter:{},regularPath:"/docs/optimization.html",relativePath:"docs/optimization.md",key:"v-1c00b5c9",path:"/docs/optimization.html",headers:[{level:2,title:"Introducing ZQuery",slug:"introducing-zquery"},{level:2,title:"Building a DataSource",slug:"building-a-datasource"},{level:2,title:"ZQuery constructors and operators",slug:"zquery-constructors-and-operators"},{level:2,title:"Using ZQuery with Caliban",slug:"using-zquery-with-caliban"},{level:2,title:"Using field metadata",slug:"using-field-metadata"},{level:2,title:"@defer support (experimental)",slug:"defer-support-experimental"},{level:3,title:"Usage",slug:"usage"}]},{title:"Relay Connections",frontmatter:{},regularPath:"/docs/relay-connections.html",relativePath:"docs/relay-connections.md",key:"v-56e4d50b",path:"/docs/relay-connections.html",headers:[{level:2,title:"Cursors",slug:"cursors"}]},{title:"Schema comparison",frontmatter:{},regularPath:"/docs/schema-comparison.html",relativePath:"docs/schema-comparison.md",key:"v-4f917bd3",path:"/docs/schema-comparison.html"},{title:"Schema Reporting",frontmatter:{},regularPath:"/docs/schema-reporting.html",relativePath:"docs/schema-reporting.md",key:"v-87b4d6ae",path:"/docs/schema-reporting.html"},{title:"Schemas",frontmatter:{},regularPath:"/docs/schema.html",relativePath:"docs/schema.md",key:"v-7bafdcee",path:"/docs/schema.html",headers:[{level:2,title:"Enums, unions, interfaces",slug:"enums-unions-interfaces"},{level:2,title:"Case classes and sealed traits",slug:"case-classes-and-sealed-traits"},{level:3,title:"Auto derivation",slug:"auto-derivation"},{level:3,title:"Semi-auto derivation",slug:"semi-auto-derivation"},{level:3,title:"Combining auto and semi-auto derivation",slug:"combining-auto-and-semi-auto-derivation"},{level:2,title:"Arguments",slug:"arguments"},{level:2,title:"Custom types",slug:"custom-types"},{level:2,title:"Effects",slug:"effects"},{level:2,title:"Annotations",slug:"annotations"},{level:2,title:"Java 8 Time types",slug:"java-8-time-types"},{level:2,title:"Code generation",slug:"code-generation"},{level:2,title:"Building Schemas by hand",slug:"building-schemas-by-hand"}]},{title:"Server code generation from schema",frontmatter:{},regularPath:"/docs/server-codegen.html",relativePath:"docs/server-codegen.md",key:"v-6abbdcee",path:"/docs/server-codegen.html",headers:[{level:3,title:"Lazy evaluation",slug:"lazy-evaluation"}]},{title:"Validation",frontmatter:{},regularPath:"/docs/validation.html",relativePath:"docs/validation.md",key:"v-300a59ee",path:"/docs/validation.html"},{title:"Stitching",frontmatter:{},regularPath:"/docs/stitching.html",relativePath:"docs/stitching.md",key:"v-ded899ca",path:"/docs/stitching.html",headers:[{level:2,title:"Dependencies",slug:"dependencies"},{level:2,title:"Stitching in Action",slug:"stitching-in-action"},{level:2,title:"Things not yet supported",slug:"things-not-yet-supported"}]},{title:"Getting Started",frontmatter:{},regularPath:"/docs/tools.html",relativePath:"docs/tools.md",key:"v-09883f07",path:"/docs/tools.html",headers:[{level:2,title:"Dependency",slug:"dependency"}]},{title:"FAQ",frontmatter:{},regularPath:"/faq/",relativePath:"faq/README.md",key:"v-40b685e4",path:"/faq/",headers:[{level:3,title:"I don't know where to start 😥",slug:"i-don-t-know-where-to-start-😥"},{level:3,title:"I'm getting a compilation error saying a Schema is missing, but I don't know which one.",slug:"i-m-getting-a-compilation-error-saying-a-schema-is-missing-but-i-don-t-know-which-one"},{level:3,title:"I want to use Caliban, but I use Cats Effect / Monix instead of ZIO.",slug:"i-want-to-use-caliban-but-i-use-cats-effect-monix-instead-of-zio"},{level:3,title:'My query fails with an "Effect failure" error. How can I get more details?',slug:"my-query-fails-with-an-effect-failure-error-how-can-i-get-more-details"},{level:3,title:"I have more than 22 fields in my Query, I can't create a case class for it.",slug:"i-have-more-than-22-fields-in-my-query-i-can-t-create-a-case-class-for-it"},{level:3,title:"How to deal with authentication/authorization?",slug:"how-to-deal-with-authentication-authorization"},{level:3,title:"I have 2 case classes with the same name (different packages). How to avoid conflicts?",slug:"i-have-2-case-classes-with-the-same-name-different-packages-how-to-avoid-conflicts"},{level:3,title:"The auto-generated schema shows a field is nullable, but I want it non-nullable instead.",slug:"the-auto-generated-schema-shows-a-field-is-nullable-but-i-want-it-non-nullable-instead"},{level:3,title:"Can I use a union as input?",slug:"can-i-use-a-union-as-input"},{level:3,title:"How to deal with recursive types?",slug:"how-to-deal-with-recursive-types"},{level:3,title:'I\'m getting a "Method too large" compiler error.',slug:"i-m-getting-a-method-too-large-compiler-error"},{level:3,title:"How can I define a Schema for a Java enum?",slug:"how-can-i-define-a-schema-for-a-java-enum"},{level:3,title:"I don't want to use Throwable as my error type",slug:"i-don-t-want-to-use-throwable-as-my-error-type"},{level:3,title:"My interface is missing from the schema",slug:"my-interface-is-missing-from-the-schema"}]},{title:"Resources",frontmatter:{},regularPath:"/resources/",relativePath:"resources/README.md",key:"v-a971ed74",path:"/resources/",headers:[{level:2,title:"Talks",slug:"talks"},{level:2,title:"Blog Articles",slug:"blog-articles"},{level:2,title:"Related Projects",slug:"related-projects"}]}],themeConfig:{logo:"/caliban.svg",locales:{"/":{selectText:"Language",label:"English",nav:[{text:"Documentation",link:"/docs/"},{text:"Resources",link:"/resources/"},{text:"FAQ",link:"/faq/"},{text:"About",link:"/about/"},{text:"Github",link:"https://github.com/ghostdogpr/caliban"},{text:"Scaladoc",link:"https://javadoc.io/doc/com.github.ghostdogpr/caliban_2.12/"}],sidebar:{"/docs/":[{title:"Caliban Server",collapsable:!0,sidebarDepth:2,children:["","schema","middleware","optimization","validation","introspection","adapters","interop","federation","relay-connections","schema-reporting","server-codegen"]},{title:"Caliban Client",collapsable:!0,sidebarDepth:2,children:["client","client-codegen","laminext"]},{title:"Caliban Tools",collapsable:!0,sidebarDepth:2,children:["tools","stitching","schema-comparison"]},{title:"Examples",path:"examples"}]}}}},locales:{"/":{lang:"en-US",title:"Caliban",description:"Functional GraphQL library for Scala",path:"/"}}};n(234);Wn.component("Badge",()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,302))),Wn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,299))),Wn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,298)));n(235);var As=[{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{}],Ts=[];class Ls extends class{constructor(){this.store=new Wn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Wn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(Ls.prototype,{getPageAsyncComponent:as,getLayoutAsyncComponent:ss,getAsyncComponent:cs,getVueComponent:us});var Rs={install(t){const e=new Ls;t.$vuepress=e,t.prototype.$vuepress=e}};function Is(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var Ms={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return fs("pageKey",e),Wn.component(e)||Wn.component(e,as(e)),Wn.component(e)?t(e):t("")}},Ds={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},Ns={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},Fs=(n(236),n(237),Object(Ss.a)(Ns,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),zs={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Wn.config.productionTip=!1,Wn.use(Va),Wn.use(Rs),Wn.mixin(function(t,e,n=Wn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const r=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(r)),i={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),i),{computed:i}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const r in t)"/"===r?n=t[r]:0===this.$page.path.indexOf(r)&&(e=t[r]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Wn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,r)=>{if(Is(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";Is(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";Is(t,o)?r(o):Is(t,n)?r(n):r()}})}(n);const r={};try{await Promise.all(As.filter(t=>"function"==typeof t).map(e=>e({Vue:Wn,options:r,router:n,siteData:Ps,isServer:t})))}catch(t){console.error(t)}return{app:new Wn(Object.assign(r,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},Ts.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file +var r=Object.freeze({}),o=Array.isArray;function i(t){return null==t}function a(t){return null!=t}function s(t){return!0===t}function c(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function u(t){return"function"==typeof t}function l(t){return null!==t&&"object"==typeof t}var f=Object.prototype.toString;function p(t){return"[object Object]"===f.call(t)}function d(t){return"[object RegExp]"===f.call(t)}function h(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function v(t){return a(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function m(t){return null==t?"":Array.isArray(t)||p(t)&&t.toString===f?JSON.stringify(t,null,2):String(t)}function y(t){var e=parseFloat(t);return isNaN(e)?t:e}function g(t,e){for(var n=Object.create(null),r=t.split(","),o=0;o-1)return t.splice(r,1)}}var x=Object.prototype.hasOwnProperty;function w(t,e){return x.call(t,e)}function C(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var O=/-(\w)/g,$=C((function(t){return t.replace(O,(function(t,e){return e?e.toUpperCase():""}))})),k=C((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),S=/\B([A-Z])/g,j=C((function(t){return t.replace(S,"-$1").toLowerCase()}));var E=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function P(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function A(t,e){for(var n in e)t[n]=e[n];return t}function T(t){for(var e={},n=0;n0,X=Q&&Q.indexOf("edge/")>0;Q&&Q.indexOf("android");var Y=Q&&/iphone|ipad|ipod|ios/.test(Q);Q&&/chrome\/\d+/.test(Q),Q&&/phantomjs/.test(Q);var tt,et=Q&&Q.match(/firefox\/(\d+)/),nt={}.watch,rt=!1;if(K)try{var ot={};Object.defineProperty(ot,"passive",{get:function(){rt=!0}}),window.addEventListener("test-passive",null,ot)}catch(t){}var it=function(){return void 0===tt&&(tt=!K&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),tt},at=K&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function st(t){return"function"==typeof t&&/native code/.test(t.toString())}var ct,ut="undefined"!=typeof Symbol&&st(Symbol)&&"undefined"!=typeof Reflect&&st(Reflect.ownKeys);ct="undefined"!=typeof Set&&st(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var lt=null;function ft(t){void 0===t&&(t=null),t||lt&<._scope.off(),lt=t,t&&t._scope.on()}var pt=function(){function t(t,e,n,r,o,i,a,s){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=o,this.ns=void 0,this.context=i,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=a,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=s,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),dt=function(t){void 0===t&&(t="");var e=new pt;return e.text=t,e.isComment=!0,e};function ht(t){return new pt(void 0,void 0,void 0,String(t))}function vt(t){var e=new pt(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var mt=0,yt=[],gt=function(){function t(){this._pending=!1,this.id=mt++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,yt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){var e=this.subs.filter((function(t){return t}));for(var n=0,r=e.length;n0&&(Qt((u=t(u,"".concat(n||"","_").concat(r)))[0])&&Qt(f)&&(p[l]=ht(f.text+u[0].text),u.shift()),p.push.apply(p,u)):c(u)?Qt(f)?p[l]=ht(f.text+u):""!==u&&p.push(ht(u)):Qt(u)&&Qt(f)?p[l]=ht(f.text+u.text):(s(e._isVList)&&a(u.tag)&&i(u.key)&&a(n)&&(u.key="__vlist".concat(n,"_").concat(r,"__")),p.push(u)));return p}(t):void 0}function Qt(t){return a(t)&&a(t.text)&&!1===t.isComment}function Jt(t,e){var n,r,i,s,c=null;if(o(t)||"string"==typeof t)for(c=new Array(t.length),n=0,r=t.length;n0,s=e?!!e.$stable:!a,c=e&&e.$key;if(e){if(e._normalized)return e._normalized;if(s&&o&&o!==r&&c===o.$key&&!a&&!o.$hasNormal)return o;for(var u in i={},e)e[u]&&"$"!==u[0]&&(i[u]=ve(t,n,u,e[u]))}else i={};for(var l in n)l in i||(i[l]=me(n,l));return e&&Object.isExtensible(e)&&(e._normalized=i),H(i,"$stable",s),H(i,"$key",c),H(i,"$hasNormal",a),i}function ve(t,e,n,r){var i=function(){var e=lt;ft(t);var n=arguments.length?r.apply(null,arguments):r({}),i=(n=n&&"object"==typeof n&&!o(n)?[n]:Kt(n))&&n[0];return ft(e),n&&(!i||1===n.length&&i.isComment&&!de(i))?void 0:n};return r.proxy&&Object.defineProperty(e,n,{get:i,enumerable:!0,configurable:!0}),i}function me(t,e){return function(){return t[e]}}function ye(t){return{get attrs(){if(!t._attrsProxy){var e=t._attrsProxy={};H(e,"_v_attr_proxy",!0),ge(e,t.$attrs,r,t,"$attrs")}return t._attrsProxy},get listeners(){t._listenersProxy||ge(t._listenersProxy={},t.$listeners,r,t,"$listeners");return t._listenersProxy},get slots(){return function(t){t._slotsProxy||_e(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(t)},emit:E(t.$emit,t),expose:function(e){e&&Object.keys(e).forEach((function(n){return zt(t,e,n)}))}}}function ge(t,e,n,r,o){var i=!1;for(var a in e)a in t?e[a]!==n[a]&&(i=!0):(i=!0,be(t,a,r,o));for(var a in t)a in e||(i=!0,delete t[a]);return i}function be(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function _e(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var xe=null;function we(t,e){return(t.__esModule||ut&&"Module"===t[Symbol.toStringTag])&&(t=t.default),l(t)?e.extend(t):t}function Ce(t){if(o(t))for(var e=0;edocument.createEvent("Event").timeStamp&&(cn=function(){return un.now()})}var ln=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function fn(){var t,e;for(sn=cn(),on=!0,tn.sort(ln),an=0;anan&&tn[n].id>t.id;)n--;tn.splice(n+1,0,t)}else tn.push(t);rn||(rn=!0,Ne(fn))}}function dn(t,e){if(t){for(var n=Object.create(null),r=ut?Reflect.ownKeys(t):Object.keys(t),o=0;o-1)if(i&&!w(o,"default"))a=!1;else if(""===a||a===j(t)){var c=In(String,o.type);(c<0||s-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!d(t)&&t.test(e)}function Jn(t,e){var n=t.cache,r=t.keys,o=t._vnode;for(var i in n){var a=n[i];if(a){var s=a.name;s&&!e(s)&&Zn(n,i,r,o)}}}function Zn(t,e,n,r){var o=t[e];!o||r&&o.tag===r.tag||o.componentInstance.$destroy(),t[e]=null,_(n,e)}Wn.prototype._init=function(t){var e=this;e._uid=Vn++,e._isVue=!0,e.__v_skip=!0,e._scope=new Ut(!0),e._scope._vm=!0,t&&t._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var o=r.componentOptions;n.propsData=o.propsData,n._parentListeners=o.listeners,n._renderChildren=o.children,n._componentTag=o.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(e,t):e.$options=En(Hn(e.constructor),t||{},e),e._renderProxy=e,e._self=e,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(e),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Ke(t,e)}(e),function(t){t._vnode=null,t._staticTrees=null;var e=t.$options,n=t.$vnode=e._parentVnode,o=n&&n.context;t.$slots=fe(e._renderChildren,o),t.$scopedSlots=n?he(t.$parent,n.data.scopedSlots,t.$slots):r,t._c=function(e,n,r,o){return Oe(t,e,n,r,o,!1)},t.$createElement=function(e,n,r,o){return Oe(t,e,n,r,o,!0)};var i=n&&n.data;At(t,"$attrs",i&&i.attrs||r,null,!0),At(t,"$listeners",e._parentListeners||r,null,!0)}(e),Ye(e,"beforeCreate",void 0,!1),function(t){var e=dn(t.$options.inject,t);e&&(St(!1),Object.keys(e).forEach((function(n){At(t,n,e[n])})),St(!0))}(e),Nn(e),function(t){var e=t.$options.provide;if(e){var n=u(e)?e.call(t):e;if(!l(n))return;for(var r=Bt(t),o=ut?Reflect.ownKeys(n):Object.keys(n),i=0;i1?P(n):n;for(var r=P(arguments,1),o='event handler for "'.concat(t,'"'),i=0,a=n.length;iparseInt(this.max)&&Zn(t,e[0],e,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Zn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Jn(t,(function(t){return Qn(e,t)}))})),this.$watch("exclude",(function(e){Jn(t,(function(t){return!Qn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=Ce(t),n=e&&e.componentOptions;if(n){var r=Kn(n),o=this.include,i=this.exclude;if(o&&(!r||!Qn(o,r))||i&&r&&Qn(i,r))return e;var a=this.cache,s=this.keys,c=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;a[c]?(e.componentInstance=a[c].componentInstance,_(s,c),s.push(c)):(this.vnodeToCache=e,this.keyToCache=c),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return B}};Object.defineProperty(t,"config",e),t.util={warn:wn,extend:A,mergeOptions:En,defineReactive:At},t.set=Tt,t.delete=Lt,t.nextTick=Ne,t.observable=function(t){return Pt(t),t},t.options=Object.create(null),F.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,A(t.options.components,Yn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=P(arguments,1);return n.unshift(this),u(t.install)?t.install.apply(t,n):u(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=En(this.options,t),this}}(t),Gn(t),function(t){F.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&p(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&u(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Wn),Object.defineProperty(Wn.prototype,"$isServer",{get:it}),Object.defineProperty(Wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Wn,"FunctionalRenderContext",{value:hn}),Wn.version="2.7.15";var tr=g("style,class"),er=g("input,textarea,option,select,progress"),nr=g("contenteditable,draggable,spellcheck"),rr=g("events,caret,typing,plaintext-only"),or=g("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),ir="http://www.w3.org/1999/xlink",ar=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},sr=function(t){return ar(t)?t.slice(6,t.length):""},cr=function(t){return null==t||!1===t};function ur(t){for(var e=t.data,n=t,r=t;a(r.componentInstance);)(r=r.componentInstance._vnode)&&r.data&&(e=lr(r.data,e));for(;a(n=n.parent);)n&&n.data&&(e=lr(e,n.data));return function(t,e){if(a(t)||a(e))return fr(t,pr(e));return""}(e.staticClass,e.class)}function lr(t,e){return{staticClass:fr(t.staticClass,e.staticClass),class:a(t.class)?[t.class,e.class]:e.class}}function fr(t,e){return t?e?t+" "+e:t:e||""}function pr(t){return Array.isArray(t)?function(t){for(var e,n="",r=0,o=t.length;r-1?Mr(t,e,n):or(e)?cr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return cr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):ar(e)?cr(n)?t.removeAttributeNS(ir,sr(e)):t.setAttributeNS(ir,e,n):Mr(t,e,n)}function Mr(t,e,n){if(cr(n))t.removeAttribute(e);else{if(J&&!Z&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Dr={create:Rr,update:Rr};function Nr(t,e){var n=e.elm,r=e.data,o=t.data;if(!(i(r.staticClass)&&i(r.class)&&(i(o)||i(o.staticClass)&&i(o.class)))){var s=ur(e),c=n._transitionClasses;a(c)&&(s=fr(s,pr(c))),s!==n._prevClass&&(n.setAttribute("class",s),n._prevClass=s)}}var zr,Fr={create:Nr,update:Nr};function Ur(t,e,n){var r=zr;return function o(){var i=e.apply(null,arguments);null!==i&&Vr(t,o,n,r)}}var Br=Pe&&!(et&&Number(et[1])<=53);function qr(t,e,n,r){if(Br){var o=sn,i=e;e=i._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=o||t.timeStamp<=0||t.target.ownerDocument!==document)return i.apply(this,arguments)}}zr.addEventListener(t,e,rt?{capture:n,passive:r}:n)}function Vr(t,e,n,r){(r||zr).removeEventListener(t,e._wrapper||e,n)}function Hr(t,e){if(!i(t.data.on)||!i(e.data.on)){var n=e.data.on||{},r=t.data.on||{};zr=e.elm||t.elm,function(t){if(a(t.__r)){var e=J?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}a(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(n),Ht(n,r,qr,Vr,Ur,e.context),zr=void 0}}var Wr,Gr={create:Hr,update:Hr,destroy:function(t){return Hr(t,Cr)}};function Kr(t,e){if(!i(t.data.domProps)||!i(e.data.domProps)){var n,r,o=e.elm,c=t.data.domProps||{},u=e.data.domProps||{};for(n in(a(u.__ob__)||s(u._v_attr_proxy))&&(u=e.data.domProps=A({},u)),c)n in u||(o[n]="");for(n in u){if(r=u[n],"textContent"===n||"innerHTML"===n){if(e.children&&(e.children.length=0),r===c[n])continue;1===o.childNodes.length&&o.removeChild(o.childNodes[0])}if("value"===n&&"PROGRESS"!==o.tagName){o._value=r;var l=i(r)?"":String(r);Qr(o,l)&&(o.value=l)}else if("innerHTML"===n&&vr(o.tagName)&&i(o.innerHTML)){(Wr=Wr||document.createElement("div")).innerHTML="".concat(r,"");for(var f=Wr.firstChild;o.firstChild;)o.removeChild(o.firstChild);for(;f.firstChild;)o.appendChild(f.firstChild)}else if(r!==c[n])try{o[n]=r}catch(t){}}}}function Qr(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,r=t._vModifiers;if(a(r)){if(r.number)return y(n)!==y(e);if(r.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Jr={create:Kr,update:Kr},Zr=C((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Xr(t){var e=Yr(t.style);return t.staticStyle?A(t.staticStyle,e):e}function Yr(t){return Array.isArray(t)?T(t):"string"==typeof t?Zr(t):t}var to,eo=/^--/,no=/\s*!important$/,ro=function(t,e,n){if(eo.test(e))t.style.setProperty(e,n);else if(no.test(n))t.style.setProperty(j(e),n.replace(no,""),"important");else{var r=io(e);if(Array.isArray(n))for(var o=0,i=n.length;o-1?e.split(co).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function lo(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(co).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function fo(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&A(e,po(t.name||"v")),A(e,t),e}return"string"==typeof t?po(t):void 0}}var po=C((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),ho=K&&!Z,vo="transition",mo="transitionend",yo="animation",go="animationend";ho&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(vo="WebkitTransition",mo="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(yo="WebkitAnimation",go="webkitAnimationEnd"));var bo=K?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function _o(t){bo((function(){bo(t)}))}function xo(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),uo(t,e))}function wo(t,e){t._transitionClasses&&_(t._transitionClasses,e),lo(t,e)}function Co(t,e,n){var r=$o(t,e),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s="transition"===o?mo:go,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout((function(){c0&&(n="transition",l=a,f=i.length):"animation"===e?u>0&&(n="animation",l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?"transition":"animation":null)?"transition"===n?i.length:c.length:0,{type:n,timeout:l,propCount:f,hasTransform:"transition"===n&&Oo.test(r[vo+"Property"])}}function ko(t,e){for(;t.length1}function To(t,e){!0!==e.data.show&&jo(e)}var Lo=function(t){var e,n,r={},u=t.modules,l=t.nodeOps;for(e=0;eh?_(t,i(n[y+1])?null:n[y+1].elm,n,d,y,r):d>y&&w(e,f,h)}(f,v,y,n,u):a(y)?(a(t.text)&&l.setTextContent(f,""),_(f,null,y,0,y.length-1,n)):a(v)?w(v,0,v.length-1):a(t.text)&&l.setTextContent(f,""):t.text!==e.text&&l.setTextContent(f,e.text),a(h)&&a(d=h.hook)&&a(d=d.postpatch)&&d(t,e)}}}function k(t,e,n){if(s(n)&&a(t.parent))t.parent.data.pendingInsert=e;else for(var r=0;r-1,a.selected!==i&&(a.selected=i);else if(M(No(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));o||(t.selectedIndex=-1)}}function Do(t,e){return e.every((function(e){return!M(e,t)}))}function No(t){return"_value"in t?t._value:t.value}function zo(t){t.target.composing=!0}function Fo(t){t.target.composing&&(t.target.composing=!1,Uo(t.target,"input"))}function Uo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Bo(t){return!t.componentInstance||t.data&&t.data.transition?t:Bo(t.componentInstance._vnode)}var qo={model:Ro,show:{bind:function(t,e,n){var r=e.value,o=(n=Bo(n)).data&&n.data.transition,i=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&o?(n.data.show=!0,jo(n,(function(){t.style.display=i}))):t.style.display=r?i:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=Bo(n)).data&&n.data.transition?(n.data.show=!0,r?jo(n,(function(){t.style.display=t.__vOriginalDisplay})):Eo(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,o){o||(t.style.display=t.__vOriginalDisplay)}}},Vo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function Ho(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Ho(Ce(e.children)):t}function Wo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var o=n._parentListeners;for(var r in o)e[$(r)]=o[r];return e}function Go(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Ko=function(t){return t.tag||de(t)},Qo=function(t){return"show"===t.name},Jo={name:"transition",props:Vo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Ko)).length){0;var r=this.mode;0;var o=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return o;var i=Ho(o);if(!i)return o;if(this._leaving)return Go(t,o);var a="__transition-".concat(this._uid,"-");i.key=null==i.key?i.isComment?a+"comment":a+i.tag:c(i.key)?0===String(i.key).indexOf(a)?i.key:a+i.key:i.key;var s=(i.data||(i.data={})).transition=Wo(this),u=this._vnode,l=Ho(u);if(i.data.directives&&i.data.directives.some(Qo)&&(i.data.show=!0),l&&l.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(i,l)&&!de(l)&&(!l.componentInstance||!l.componentInstance._vnode.isComment)){var f=l.data.transition=A({},s);if("out-in"===r)return this._leaving=!0,Wt(f,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),Go(t,o);if("in-out"===r){if(de(i))return u;var p,d=function(){p()};Wt(s,"afterEnter",d),Wt(s,"enterCancelled",d),Wt(f,"delayLeave",(function(t){p=t}))}}return o}}},Zo=A({tag:String,moveClass:String},Vo);function Xo(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function Yo(t){t.data.newPos=t.elm.getBoundingClientRect()}function ti(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,o=e.top-n.top;if(r||o){t.data.moved=!0;var i=t.elm.style;i.transform=i.WebkitTransform="translate(".concat(r,"px,").concat(o,"px)"),i.transitionDuration="0s"}}delete Zo.mode;var ei={Transition:Jo,TransitionGroup:{props:Zo,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var o=Je(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,o(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,o=this.$slots.default||[],i=this.children=[],a=Wo(this),s=0;s-1?yr[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:yr[t]=/HTMLUnknownElement/.test(e.toString())},A(Wn.options.directives,qo),A(Wn.options.components,ei),Wn.prototype.__patch__=K?Lo:L,Wn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=dt),Ye(t,"beforeMount"),r=function(){t._update(t._render(),n)},new Ve(t,r,L,{before:function(){t._isMounted&&!t._isDestroyed&&Ye(t,"beforeUpdate")}},!0),n=!1;var o=t._preWatchers;if(o)for(var i=0;i=0&&(e=t.slice(r),t=t.slice(0,r));var o=t.indexOf("?");return o>=0&&(n=t.slice(o+1),t=t.slice(0,o)),{path:t,query:n,hash:e}}(o.path||""),u=e&&e.path||"/",l=c.path?wi(c.path,u,n||o.append):u,f=function(t,e,n){void 0===e&&(e={});var r,o=n||ui;try{r=o(t||"")}catch(t){r={}}for(var i in e){var a=e[i];r[i]=Array.isArray(a)?a.map(ci):ci(a)}return r}(c.query,o.query,r&&r.options.parseQuery),p=o.hash||c.hash;return p&&"#"!==p.charAt(0)&&(p="#"+p),{_normalized:!0,path:l,query:f,hash:p}}var qi,Vi=function(){},Hi={name:"RouterLink",props:{to:{type:[String,Object],required:!0},tag:{type:String,default:"a"},custom:Boolean,exact:Boolean,exactPath:Boolean,append:Boolean,replace:Boolean,activeClass:String,exactActiveClass:String,ariaCurrentValue:{type:String,default:"page"},event:{type:[String,Array],default:"click"}},render:function(t){var e=this,n=this.$router,r=this.$route,o=n.resolve(this.to,r,this.append),i=o.location,a=o.route,s=o.href,c={},u=n.options.linkActiveClass,l=n.options.linkExactActiveClass,f=null==u?"router-link-active":u,p=null==l?"router-link-exact-active":l,d=null==this.activeClass?f:this.activeClass,h=null==this.exactActiveClass?p:this.exactActiveClass,v=a.redirectedFrom?pi(null,Bi(a.redirectedFrom),null,n):a;c[h]=yi(r,v,this.exactPath),c[d]=this.exact||this.exactPath?c[h]:function(t,e){return 0===t.path.replace(fi,"/").indexOf(e.path.replace(fi,"/"))&&(!e.hash||t.hash===e.hash)&&function(t,e){for(var n in e)if(!(n in t))return!1;return!0}(t.query,e.query)}(r,v);var m=c[h]?this.ariaCurrentValue:null,y=function(t){Wi(t)&&(e.replace?n.replace(i,Vi):n.push(i,Vi))},g={click:Wi};Array.isArray(this.event)?this.event.forEach((function(t){g[t]=y})):g[this.event]=y;var b={class:c},_=!this.$scopedSlots.$hasNormal&&this.$scopedSlots.default&&this.$scopedSlots.default({href:s,route:a,navigate:y,isActive:c[d],isExactActive:c[h]});if(_){if(1===_.length)return _[0];if(_.length>1||!_.length)return 0===_.length?t():t("span",{},_)}if("a"===this.tag)b.on=g,b.attrs={href:s,"aria-current":m};else{var x=function t(e){var n;if(e)for(var r=0;r-1&&(s.params[p]=n.params[p]);return s.path=Ui(l.path,s.params),c(l,s,a)}if(s.path){s.params={};for(var d=0;d-1}function Ca(t,e){return wa(t)&&t._isRouter&&(null==e||t.type===e)}function Oa(t,e,n){var r=function(o){o>=t.length?n():t[o]?e(t[o],(function(){r(o+1)})):r(o+1)};r(0)}function $a(t){return function(e,n,r){var o=!1,i=0,a=null;ka(t,(function(t,e,n,s){if("function"==typeof t&&void 0===t.cid){o=!0,i++;var c,u=Ea((function(e){var o;((o=e).__esModule||ja&&"Module"===o[Symbol.toStringTag])&&(e=e.default),t.resolved="function"==typeof e?e:qi.extend(e),n.components[s]=e,--i<=0&&r()})),l=Ea((function(t){var e="Failed to resolve async component "+s+": "+t;a||(a=wa(t)?t:new Error(e),r(a))}));try{c=t(u,l)}catch(t){l(t)}if(c)if("function"==typeof c.then)c.then(u,l);else{var f=c.component;f&&"function"==typeof f.then&&f.then(u,l)}}})),o||r()}}function ka(t,e){return Sa(t.map((function(t){return Object.keys(t.components).map((function(n){return e(t.components[n],t.instances[n],t,n)}))})))}function Sa(t){return Array.prototype.concat.apply([],t)}var ja="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag;function Ea(t){var e=!1;return function(){for(var n=[],r=arguments.length;r--;)n[r]=arguments[r];if(!e)return e=!0,t.apply(this,n)}}var Pa=function(t,e){this.router=t,this.base=function(t){if(!t)if(Gi){var e=document.querySelector("base");t=(t=e&&e.getAttribute("href")||"/").replace(/^https?:\/\/[^\/]+/,"")}else t="/";"/"!==t.charAt(0)&&(t="/"+t);return t.replace(/\/$/,"")}(e),this.current=hi,this.pending=null,this.ready=!1,this.readyCbs=[],this.readyErrorCbs=[],this.errorCbs=[],this.listeners=[]};function Aa(t,e,n,r){var o=ka(t,(function(t,r,o,i){var a=function(t,e){"function"!=typeof t&&(t=qi.extend(t));return t.options[e]}(t,e);if(a)return Array.isArray(a)?a.map((function(t){return n(t,r,o,i)})):n(a,r,o,i)}));return Sa(r?o.reverse():o)}function Ta(t,e){if(e)return function(){return t.apply(e,arguments)}}Pa.prototype.listen=function(t){this.cb=t},Pa.prototype.onReady=function(t,e){this.ready?t():(this.readyCbs.push(t),e&&this.readyErrorCbs.push(e))},Pa.prototype.onError=function(t){this.errorCbs.push(t)},Pa.prototype.transitionTo=function(t,e,n){var r,o=this;try{r=this.router.match(t,this.current)}catch(t){throw this.errorCbs.forEach((function(e){e(t)})),t}var i=this.current;this.confirmTransition(r,(function(){o.updateRoute(r),e&&e(r),o.ensureURL(),o.router.afterHooks.forEach((function(t){t&&t(r,i)})),o.ready||(o.ready=!0,o.readyCbs.forEach((function(t){t(r)})))}),(function(t){n&&n(t),t&&!o.ready&&(Ca(t,ya.redirected)&&i===hi||(o.ready=!0,o.readyErrorCbs.forEach((function(e){e(t)}))))}))},Pa.prototype.confirmTransition=function(t,e,n){var r=this,o=this.current;this.pending=t;var i,a,s=function(t){!Ca(t)&&wa(t)&&(r.errorCbs.length?r.errorCbs.forEach((function(e){e(t)})):console.error(t)),n&&n(t)},c=t.matched.length-1,u=o.matched.length-1;if(yi(t,o)&&c===u&&t.matched[c]===o.matched[u])return this.ensureURL(),t.hash&&ia(this.router,o,t,!1),s(((a=_a(i=o,t,ya.duplicated,'Avoided redundant navigation to current location: "'+i.fullPath+'".')).name="NavigationDuplicated",a));var l=function(t,e){var n,r=Math.max(t.length,e.length);for(n=0;n0)){var e=this.router,n=e.options.scrollBehavior,r=ha&&n;r&&this.listeners.push(oa());var o=function(){var n=t.current,o=Ra(t.base);t.current===hi&&o===t._startLocation||t.transitionTo(o,(function(t){r&&ia(e,t,n,!0)}))};window.addEventListener("popstate",o),this.listeners.push((function(){window.removeEventListener("popstate",o)}))}},e.prototype.go=function(t){window.history.go(t)},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){va(Ci(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){ma(Ci(r.base+t.fullPath)),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.ensureURL=function(t){if(Ra(this.base)!==this.current.fullPath){var e=Ci(this.base+this.current.fullPath);t?va(e):ma(e)}},e.prototype.getCurrentLocation=function(){return Ra(this.base)},e}(Pa);function Ra(t){var e=window.location.pathname,n=e.toLowerCase(),r=t.toLowerCase();return!t||n!==r&&0!==n.indexOf(Ci(r+"/"))||(e=e.slice(t.length)),(e||"/")+window.location.search+window.location.hash}var Ia=function(t){function e(e,n,r){t.call(this,e,n),r&&function(t){var e=Ra(t);if(!/^\/#/.test(e))return window.location.replace(Ci(t+"/#"+e)),!0}(this.base)||Ma()}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.setupListeners=function(){var t=this;if(!(this.listeners.length>0)){var e=this.router.options.scrollBehavior,n=ha&&e;n&&this.listeners.push(oa());var r=function(){var e=t.current;Ma()&&t.transitionTo(Da(),(function(r){n&&ia(t.router,r,e,!0),ha||Fa(r.fullPath)}))},o=ha?"popstate":"hashchange";window.addEventListener(o,r),this.listeners.push((function(){window.removeEventListener(o,r)}))}},e.prototype.push=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){za(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this,o=this.current;this.transitionTo(t,(function(t){Fa(t.fullPath),ia(r.router,t,o,!1),e&&e(t)}),n)},e.prototype.go=function(t){window.history.go(t)},e.prototype.ensureURL=function(t){var e=this.current.fullPath;Da()!==e&&(t?za(e):Fa(e))},e.prototype.getCurrentLocation=function(){return Da()},e}(Pa);function Ma(){var t=Da();return"/"===t.charAt(0)||(Fa("/"+t),!1)}function Da(){var t=window.location.href,e=t.indexOf("#");return e<0?"":t=t.slice(e+1)}function Na(t){var e=window.location.href,n=e.indexOf("#");return(n>=0?e.slice(0,n):e)+"#"+t}function za(t){ha?va(Na(t)):window.location.hash=t}function Fa(t){ha?ma(Na(t)):window.location.replace(Na(t))}var Ua=function(t){function e(e,n){t.call(this,e,n),this.stack=[],this.index=-1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.push=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index+1).concat(t),r.index++,e&&e(t)}),n)},e.prototype.replace=function(t,e,n){var r=this;this.transitionTo(t,(function(t){r.stack=r.stack.slice(0,r.index).concat(t),e&&e(t)}),n)},e.prototype.go=function(t){var e=this,n=this.index+t;if(!(n<0||n>=this.stack.length)){var r=this.stack[n];this.confirmTransition(r,(function(){var t=e.current;e.index=n,e.updateRoute(r),e.router.afterHooks.forEach((function(e){e&&e(r,t)}))}),(function(t){Ca(t,ya.duplicated)&&(e.index=n)}))}},e.prototype.getCurrentLocation=function(){var t=this.stack[this.stack.length-1];return t?t.fullPath:"/"},e.prototype.ensureURL=function(){},e}(Pa),Ba=function(t){void 0===t&&(t={}),this.app=null,this.apps=[],this.options=t,this.beforeHooks=[],this.resolveHooks=[],this.afterHooks=[],this.matcher=Ji(t.routes||[],this);var e=t.mode||"hash";switch(this.fallback="history"===e&&!ha&&!1!==t.fallback,this.fallback&&(e="hash"),Gi||(e="abstract"),this.mode=e,e){case"history":this.history=new La(this,t.base);break;case"hash":this.history=new Ia(this,t.base,this.fallback);break;case"abstract":this.history=new Ua(this,t.base);break;default:0}},qa={currentRoute:{configurable:!0}};Ba.prototype.match=function(t,e,n){return this.matcher.match(t,e,n)},qa.currentRoute.get=function(){return this.history&&this.history.current},Ba.prototype.init=function(t){var e=this;if(this.apps.push(t),t.$once("hook:destroyed",(function(){var n=e.apps.indexOf(t);n>-1&&e.apps.splice(n,1),e.app===t&&(e.app=e.apps[0]||null),e.app||e.history.teardown()})),!this.app){this.app=t;var n=this.history;if(n instanceof La||n instanceof Ia){var r=function(t){n.setupListeners(),function(t){var r=n.current,o=e.options.scrollBehavior;ha&&o&&"fullPath"in t&&ia(e,t,r,!1)}(t)};n.transitionTo(n.getCurrentLocation(),r,r)}n.listen((function(t){e.apps.forEach((function(e){e._route=t}))}))}},Ba.prototype.beforeEach=function(t){return Ha(this.beforeHooks,t)},Ba.prototype.beforeResolve=function(t){return Ha(this.resolveHooks,t)},Ba.prototype.afterEach=function(t){return Ha(this.afterHooks,t)},Ba.prototype.onReady=function(t,e){this.history.onReady(t,e)},Ba.prototype.onError=function(t){this.history.onError(t)},Ba.prototype.push=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.push(t,e,n)}));this.history.push(t,e,n)},Ba.prototype.replace=function(t,e,n){var r=this;if(!e&&!n&&"undefined"!=typeof Promise)return new Promise((function(e,n){r.history.replace(t,e,n)}));this.history.replace(t,e,n)},Ba.prototype.go=function(t){this.history.go(t)},Ba.prototype.back=function(){this.go(-1)},Ba.prototype.forward=function(){this.go(1)},Ba.prototype.getMatchedComponents=function(t){var e=t?t.matched?t:this.resolve(t).route:this.currentRoute;return e?[].concat.apply([],e.matched.map((function(t){return Object.keys(t.components).map((function(e){return t.components[e]}))}))):[]},Ba.prototype.resolve=function(t,e,n){var r=Bi(t,e=e||this.history.current,n,this),o=this.match(r,e),i=o.redirectedFrom||o.fullPath;return{location:r,route:o,href:function(t,e,n){var r="hash"===n?"#"+e:e;return t?Ci(t+"/"+r):r}(this.history.base,i,this.mode),normalizedTo:r,resolved:o}},Ba.prototype.getRoutes=function(){return this.matcher.getRoutes()},Ba.prototype.addRoute=function(t,e){this.matcher.addRoute(t,e),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Ba.prototype.addRoutes=function(t){this.matcher.addRoutes(t),this.history.current!==hi&&this.history.transitionTo(this.history.getCurrentLocation())},Object.defineProperties(Ba.prototype,qa);var Va=Ba;function Ha(t,e){return t.push(e),function(){var n=t.indexOf(e);n>-1&&t.splice(n,1)}}Ba.install=function t(e){if(!t.installed||qi!==e){t.installed=!0,qi=e;var n=function(t){return void 0!==t},r=function(t,e){var r=t.$options._parentVnode;n(r)&&n(r=r.data)&&n(r=r.registerRouteInstance)&&r(t,e)};e.mixin({beforeCreate:function(){n(this.$options.router)?(this._routerRoot=this,this._router=this.$options.router,this._router.init(this),e.util.defineReactive(this,"_route",this._router.history.current)):this._routerRoot=this.$parent&&this.$parent._routerRoot||this,r(this,this)},destroyed:function(){r(this)}}),Object.defineProperty(e.prototype,"$router",{get:function(){return this._routerRoot._router}}),Object.defineProperty(e.prototype,"$route",{get:function(){return this._routerRoot._route}}),e.component("RouterView",_i),e.component("RouterLink",Hi);var o=e.config.optionMergeStrategies;o.beforeRouteEnter=o.beforeRouteLeave=o.beforeRouteUpdate=o.created}},Ba.version="3.6.5",Ba.isNavigationFailure=Ca,Ba.NavigationFailureType=ya,Ba.START_LOCATION=hi,Gi&&window.Vue&&window.Vue.use(Ba);n(97);n(90),n(127);var Wa={"components/AlgoliaSearchBox":()=>Promise.all([n.e(0),n.e(13)]).then(n.bind(null,297)),"components/DropdownLink":()=>Promise.all([n.e(0),n.e(14)]).then(n.bind(null,254)),"components/DropdownTransition":()=>Promise.all([n.e(0),n.e(19)]).then(n.bind(null,242)),"components/Home":()=>Promise.all([n.e(0),n.e(16)]).then(n.bind(null,280)),"components/NavLink":()=>n.e(21).then(n.bind(null,241)),"components/NavLinks":()=>Promise.all([n.e(0),n.e(12)]).then(n.bind(null,265)),"components/Navbar":()=>Promise.all([n.e(0),n.e(1)]).then(n.bind(null,294)),"components/Page":()=>Promise.all([n.e(0),n.e(11)]).then(n.bind(null,281)),"components/PageEdit":()=>Promise.all([n.e(0),n.e(17)]).then(n.bind(null,267)),"components/PageNav":()=>Promise.all([n.e(0),n.e(15)]).then(n.bind(null,268)),"components/Sidebar":()=>Promise.all([n.e(0),n.e(10)]).then(n.bind(null,282)),"components/SidebarButton":()=>Promise.all([n.e(0),n.e(20)]).then(n.bind(null,283)),"components/SidebarGroup":()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,266)),"components/SidebarLink":()=>Promise.all([n.e(0),n.e(18)]).then(n.bind(null,255)),"components/SidebarLinks":()=>Promise.all([n.e(0),n.e(3)]).then(n.bind(null,253)),"global-components/Badge":()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,302)),"global-components/CodeBlock":()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,298)),"global-components/CodeGroup":()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,299)),"layouts/404":()=>n.e(7).then(n.bind(null,300)),"layouts/Layout":()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,301)),NotFound:()=>n.e(7).then(n.bind(null,300)),Layout:()=>Promise.all([n.e(0),n.e(1),n.e(2)]).then(n.bind(null,301))},Ga={"v-3c88bbf2":()=>n.e(22).then(n.bind(null,303)),"v-0decf914":()=>n.e(23).then(n.bind(null,304)),"v-d7e5bcfc":()=>n.e(24).then(n.bind(null,305)),"v-c864372e":()=>n.e(25).then(n.bind(null,306)),"v-102beaee":()=>n.e(26).then(n.bind(null,307)),"v-23f0ba6e":()=>n.e(27).then(n.bind(null,308)),"v-4419f5c9":()=>n.e(28).then(n.bind(null,309)),"v-05e5796e":()=>n.e(29).then(n.bind(null,310)),"v-6d148503":()=>n.e(30).then(n.bind(null,311)),"v-70457f72":()=>n.e(31).then(n.bind(null,312)),"v-41c3bc69":()=>n.e(32).then(n.bind(null,313)),"v-2bf9c0ae":()=>n.e(33).then(n.bind(null,314)),"v-1c00b5c9":()=>n.e(34).then(n.bind(null,315)),"v-56e4d50b":()=>n.e(35).then(n.bind(null,316)),"v-4f917bd3":()=>n.e(36).then(n.bind(null,317)),"v-87b4d6ae":()=>n.e(37).then(n.bind(null,318)),"v-7bafdcee":()=>n.e(38).then(n.bind(null,319)),"v-6abbdcee":()=>n.e(39).then(n.bind(null,320)),"v-ded899ca":()=>n.e(40).then(n.bind(null,321)),"v-09883f07":()=>n.e(41).then(n.bind(null,322)),"v-300a59ee":()=>n.e(42).then(n.bind(null,323)),"v-40b685e4":()=>n.e(43).then(n.bind(null,324)),"v-a971ed74":()=>n.e(44).then(n.bind(null,325))};function Ka(t){const e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}const Qa=/-(\w)/g,Ja=Ka(t=>t.replace(Qa,(t,e)=>e?e.toUpperCase():"")),Za=/\B([A-Z])/g,Xa=Ka(t=>t.replace(Za,"-$1").toLowerCase()),Ya=Ka(t=>t.charAt(0).toUpperCase()+t.slice(1));function ts(t,e){if(!e)return;if(t(e))return t(e);return e.includes("-")?t(Ya(Ja(e))):t(Ya(e))||t(Xa(e))}const es=Object.assign({},Wa,Ga),ns=t=>es[t],rs=t=>Ga[t],os=t=>Wa[t],is=t=>Wn.component(t);function as(t){return ts(rs,t)}function ss(t){return ts(os,t)}function cs(t){return ts(ns,t)}function us(t){return ts(is,t)}function ls(...t){return Promise.all(t.filter(t=>t).map(async t=>{if(!us(t)&&cs(t)){const e=await cs(t)();Wn.component(t,e.default)}}))}function fs(t,e){"undefined"!=typeof window&&window.__VUEPRESS__&&(window.__VUEPRESS__[t]=e)}var ps=n(87),ds=n.n(ps),hs=n(88),vs=n.n(hs),ms={created(){if(this.siteMeta=this.$site.headTags.filter(([t])=>"meta"===t).map(([t,e])=>e),this.$ssrContext){const e=this.getMergedMetaTags();this.$ssrContext.title=this.$title,this.$ssrContext.lang=this.$lang,this.$ssrContext.pageMeta=(t=e)?t.map(t=>{let e="{e+=` ${n}="${vs()(t[n])}"`}),e+">"}).join("\n "):"",this.$ssrContext.canonicalLink=gs(this.$canonicalUrl)}var t},mounted(){this.currentMetaTags=[...document.querySelectorAll("meta")],this.updateMeta(),this.updateCanonicalLink()},methods:{updateMeta(){document.title=this.$title,document.documentElement.lang=this.$lang;const t=this.getMergedMetaTags();this.currentMetaTags=bs(t,this.currentMetaTags)},getMergedMetaTags(){const t=this.$page.frontmatter.meta||[];return ds()([{name:"description",content:this.$description}],t,this.siteMeta,_s)},updateCanonicalLink(){ys(),this.$canonicalUrl&&document.head.insertAdjacentHTML("beforeend",gs(this.$canonicalUrl))}},watch:{$page(){this.updateMeta(),this.updateCanonicalLink()}},beforeDestroy(){bs(null,this.currentMetaTags),ys()}};function ys(){const t=document.querySelector("link[rel='canonical']");t&&t.remove()}function gs(t=""){return t?``:""}function bs(t,e){if(e&&[...e].filter(t=>t.parentNode===document.head).forEach(t=>document.head.removeChild(t)),t)return t.map(t=>{const e=document.createElement("meta");return Object.keys(t).forEach(n=>{e.setAttribute(n,t[n])}),document.head.appendChild(e),e})}function _s(t){for(const e of["name","property","itemprop"])if(t.hasOwnProperty(e))return t[e]+e;return JSON.stringify(t)}var xs=n(89),ws={mounted(){window.addEventListener("scroll",this.onScroll)},methods:{onScroll:n.n(xs)()((function(){this.setActiveHash()}),300),setActiveHash(){const t=[].slice.call(document.querySelectorAll(".sidebar-link")),e=[].slice.call(document.querySelectorAll(".header-anchor")).filter(e=>t.some(t=>t.hash===e.hash)),n=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),r=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),o=window.innerHeight+n;for(let t=0;t=i.parentElement.offsetTop+10&&(!a||n{this.$nextTick(()=>{this.$vuepress.$set("disableScrollBehavior",!1)})})}}}},beforeDestroy(){window.removeEventListener("scroll",this.onScroll)}},Cs=n(22),Os=n.n(Cs),$s=[ms,ws,{mounted(){Os.a.configure({showSpinner:!1}),this.$router.beforeEach((t,e,n)=>{t.path===e.path||Wn.component(t.name)||Os.a.start(),n()}),this.$router.afterEach(()=>{Os.a.done(),this.isSidebarOpen=!1})}}],ks={name:"GlobalLayout",computed:{layout(){const t=this.getLayout();return fs("layout",t),Wn.component(t)}},methods:{getLayout(){if(this.$page.path){const t=this.$page.frontmatter.layout;return t&&(this.$vuepress.getLayoutAsyncComponent(t)||this.$vuepress.getVueComponent(t))?t:"Layout"}return"NotFound"}}},Ss=n(14),js=Object(Ss.a)(ks,(function(){return(0,this._self._c)(this.layout,{tag:"component"})}),[],!1,null,null,null).exports;!function(t,e,n){switch(e){case"components":t[e]||(t[e]={}),Object.assign(t[e],n);break;case"mixins":t[e]||(t[e]=[]),t[e].push(...n);break;default:throw new Error("Unknown option name.")}}(js,"mixins",$s);const Es=[{name:"v-3c88bbf2",path:"/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-3c88bbf2").then(n)}},{path:"/index.html",redirect:"/"},{name:"v-0decf914",path:"/about/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-0decf914").then(n)}},{path:"/about/index.html",redirect:"/about/"},{name:"v-d7e5bcfc",path:"/docs/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-d7e5bcfc").then(n)}},{path:"/docs/index.html",redirect:"/docs/"},{name:"v-c864372e",path:"/docs/adapters.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-c864372e").then(n)}},{name:"v-102beaee",path:"/docs/client-codegen.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-102beaee").then(n)}},{name:"v-23f0ba6e",path:"/docs/client.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-23f0ba6e").then(n)}},{name:"v-4419f5c9",path:"/docs/examples.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-4419f5c9").then(n)}},{name:"v-05e5796e",path:"/docs/federation.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-05e5796e").then(n)}},{name:"v-6d148503",path:"/docs/interop.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-6d148503").then(n)}},{name:"v-70457f72",path:"/docs/introspection.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-70457f72").then(n)}},{name:"v-41c3bc69",path:"/docs/laminext.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-41c3bc69").then(n)}},{name:"v-2bf9c0ae",path:"/docs/middleware.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-2bf9c0ae").then(n)}},{name:"v-1c00b5c9",path:"/docs/optimization.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-1c00b5c9").then(n)}},{name:"v-56e4d50b",path:"/docs/relay-connections.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-56e4d50b").then(n)}},{name:"v-4f917bd3",path:"/docs/schema-comparison.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-4f917bd3").then(n)}},{name:"v-87b4d6ae",path:"/docs/schema-reporting.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-87b4d6ae").then(n)}},{name:"v-7bafdcee",path:"/docs/schema.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-7bafdcee").then(n)}},{name:"v-6abbdcee",path:"/docs/server-codegen.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-6abbdcee").then(n)}},{name:"v-ded899ca",path:"/docs/stitching.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-ded899ca").then(n)}},{name:"v-09883f07",path:"/docs/tools.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-09883f07").then(n)}},{name:"v-300a59ee",path:"/docs/validation.html",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-300a59ee").then(n)}},{name:"v-40b685e4",path:"/faq/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-40b685e4").then(n)}},{path:"/faq/index.html",redirect:"/faq/"},{name:"v-a971ed74",path:"/resources/",component:js,beforeEnter:(t,e,n)=>{ls("Layout","v-a971ed74").then(n)}},{path:"/resources/index.html",redirect:"/resources/"},{path:"*",component:js}],Ps={title:"",description:"",base:"/caliban/",headTags:[["link",{rel:"icon",href:"/caliban/caliban.png"}]],pages:[{title:"Home",frontmatter:{home:!0,heroImage:"/caliban.svg",actionText:"Get Started →",actionLink:"/docs/",features:[{title:"High performance",details:"While every public interface is pure and immutable, library internals have been optimized for speed."},{title:"Minimal boilerplate",details:"No need to manually define a schema for every type in your API. Let the compiler do the boring work."},{title:"Excellent interoperability",details:"Out-of-the-box support for major HTTP server libraries, effect types, Json libraries and more."}]},regularPath:"/",relativePath:"README.md",key:"v-3c88bbf2",path:"/"},{title:"About",frontmatter:{},regularPath:"/about/",relativePath:"about/README.md",key:"v-0decf914",path:"/about/"},{title:"Getting Started",frontmatter:{},regularPath:"/docs/",relativePath:"docs/README.md",key:"v-d7e5bcfc",path:"/docs/",headers:[{level:2,title:"A simple example",slug:"a-simple-example"},{level:2,title:"Mutations",slug:"mutations"},{level:2,title:"Subscriptions",slug:"subscriptions"},{level:2,title:"Serving over HTTP",slug:"serving-over-http"},{level:2,title:"Interop with 3rd-party libraries",slug:"interop-with-3rd-party-libraries"}]},{title:"Http Adapters",frontmatter:{},regularPath:"/docs/adapters.html",relativePath:"docs/adapters.md",key:"v-c864372e",path:"/docs/adapters.html",headers:[{level:2,title:"Built-in tapir adapters",slug:"built-in-tapir-adapters"},{level:2,title:"Json handling",slug:"json-handling"},{level:2,title:"Make your own adapter",slug:"make-your-own-adapter"},{level:2,title:"High-performance QuickAdapter",slug:"high-performance-quickadapter"},{level:3,title:"Usage",slug:"usage"},{level:3,title:"Customization",slug:"customization"}]},{title:"Code Generation",frontmatter:{},regularPath:"/docs/client-codegen.html",relativePath:"docs/client-codegen.md",key:"v-102beaee",path:"/docs/client-codegen.html",headers:[{level:2,title:"CalibanPlugin",slug:"calibanplugin"},{level:3,title:"From a schema file",slug:"from-a-schema-file"},{level:3,title:"From a server URL",slug:"from-a-server-url"},{level:3,title:"Generation settings",slug:"generation-settings"},{level:3,title:"Manual generation",slug:"manual-generation"},{level:2,title:"CompileTimeCalibanPlugin",slug:"compiletimecalibanplugin"},{level:3,title:"Server side configuration",slug:"server-side-configuration"},{level:3,title:"Client side configuration",slug:"client-side-configuration"},{level:3,title:"Additional information about CompileTimeCalibanPlugin",slug:"additional-information-about-compiletimecalibanplugin"}]},{title:"Getting Started",frontmatter:{},regularPath:"/docs/client.html",relativePath:"docs/client.md",key:"v-23f0ba6e",path:"/docs/client.html",headers:[{level:2,title:"Dependencies",slug:"dependencies"},{level:2,title:"Code generation",slug:"code-generation"},{level:2,title:"Query building",slug:"query-building"},{level:2,title:"Request execution",slug:"request-execution"}]},{title:"Examples",frontmatter:{},regularPath:"/docs/examples.html",relativePath:"docs/examples.md",key:"v-4419f5c9",path:"/docs/examples.html"},{title:"Federation",frontmatter:{},regularPath:"/docs/federation.html",relativePath:"docs/federation.md",key:"v-05e5796e",path:"/docs/federation.html",headers:[{level:2,title:"Dependencies",slug:"dependencies"},{level:2,title:"Federating",slug:"federating"},{level:2,title:"Tracing",slug:"tracing"},{level:2,title:"Federation V2",slug:"federation-v2"},{level:3,title:"Customizing Federation",slug:"customizing-federation"}]},{title:"Interop",frontmatter:{},regularPath:"/docs/interop.html",relativePath:"docs/interop.md",key:"v-6d148503",path:"/docs/interop.html",headers:[{level:2,title:"Cats Effect",slug:"cats-effect"},{level:2,title:"Monix (only with cats-effect 2.x)",slug:"monix-only-with-cats-effect-2-x"},{level:2,title:"Tapir",slug:"tapir"},{level:3,title:"GraphQL restrictions",slug:"graphql-restrictions"}]},{title:"Introspection",frontmatter:{},regularPath:"/docs/introspection.html",relativePath:"docs/introspection.md",key:"v-70457f72",path:"/docs/introspection.html"},{title:"Laminext Integration",frontmatter:{},regularPath:"/docs/laminext.html",relativePath:"docs/laminext.md",key:"v-41c3bc69",path:"/docs/laminext.html"},{title:"Middleware",frontmatter:{},regularPath:"/docs/middleware.html",relativePath:"docs/middleware.md",key:"v-2bf9c0ae",path:"/docs/middleware.html",headers:[{level:2,title:"Wrapper types",slug:"wrapper-types"},{level:2,title:"Pre-defined wrappers",slug:"pre-defined-wrappers"},{level:2,title:"Wrapping the interpreter",slug:"wrapping-the-interpreter"},{level:2,title:"Customizing error responses",slug:"customizing-error-responses"},{level:2,title:"Wrapping the GraphQL",slug:"wrapping-the-graphql"},{level:2,title:"Cost Estimation",slug:"cost-estimation"},{level:2,title:"OpenTelemetry Tracing",slug:"opentelemetry-tracing"}]},{title:"Query optimization",frontmatter:{},regularPath:"/docs/optimization.html",relativePath:"docs/optimization.md",key:"v-1c00b5c9",path:"/docs/optimization.html",headers:[{level:2,title:"Introducing ZQuery",slug:"introducing-zquery"},{level:2,title:"Building a DataSource",slug:"building-a-datasource"},{level:2,title:"ZQuery constructors and operators",slug:"zquery-constructors-and-operators"},{level:2,title:"Using ZQuery with Caliban",slug:"using-zquery-with-caliban"},{level:2,title:"Using field metadata",slug:"using-field-metadata"},{level:2,title:"@defer support (experimental)",slug:"defer-support-experimental"},{level:3,title:"Usage",slug:"usage"}]},{title:"Relay Connections",frontmatter:{},regularPath:"/docs/relay-connections.html",relativePath:"docs/relay-connections.md",key:"v-56e4d50b",path:"/docs/relay-connections.html",headers:[{level:2,title:"Cursors",slug:"cursors"}]},{title:"Schema comparison",frontmatter:{},regularPath:"/docs/schema-comparison.html",relativePath:"docs/schema-comparison.md",key:"v-4f917bd3",path:"/docs/schema-comparison.html"},{title:"Schema Reporting",frontmatter:{},regularPath:"/docs/schema-reporting.html",relativePath:"docs/schema-reporting.md",key:"v-87b4d6ae",path:"/docs/schema-reporting.html"},{title:"Schemas",frontmatter:{},regularPath:"/docs/schema.html",relativePath:"docs/schema.md",key:"v-7bafdcee",path:"/docs/schema.html",headers:[{level:2,title:"Enums, unions, interfaces",slug:"enums-unions-interfaces"},{level:2,title:"Case classes and sealed traits",slug:"case-classes-and-sealed-traits"},{level:3,title:"Auto derivation",slug:"auto-derivation"},{level:3,title:"Semi-auto derivation",slug:"semi-auto-derivation"},{level:3,title:"Combining auto and semi-auto derivation",slug:"combining-auto-and-semi-auto-derivation"},{level:2,title:"Arguments",slug:"arguments"},{level:2,title:"Custom types",slug:"custom-types"},{level:2,title:"Effects",slug:"effects"},{level:2,title:"Annotations",slug:"annotations"},{level:2,title:"Java 8 Time types",slug:"java-8-time-types"},{level:2,title:"Code generation",slug:"code-generation"},{level:2,title:"Building Schemas by hand",slug:"building-schemas-by-hand"}]},{title:"Server code generation from schema",frontmatter:{},regularPath:"/docs/server-codegen.html",relativePath:"docs/server-codegen.md",key:"v-6abbdcee",path:"/docs/server-codegen.html",headers:[{level:3,title:"Lazy evaluation",slug:"lazy-evaluation"}]},{title:"Stitching",frontmatter:{},regularPath:"/docs/stitching.html",relativePath:"docs/stitching.md",key:"v-ded899ca",path:"/docs/stitching.html",headers:[{level:2,title:"Dependencies",slug:"dependencies"},{level:2,title:"Stitching in Action",slug:"stitching-in-action"},{level:2,title:"Things not yet supported",slug:"things-not-yet-supported"}]},{title:"Getting Started",frontmatter:{},regularPath:"/docs/tools.html",relativePath:"docs/tools.md",key:"v-09883f07",path:"/docs/tools.html",headers:[{level:2,title:"Dependency",slug:"dependency"}]},{title:"Validation",frontmatter:{},regularPath:"/docs/validation.html",relativePath:"docs/validation.md",key:"v-300a59ee",path:"/docs/validation.html"},{title:"FAQ",frontmatter:{},regularPath:"/faq/",relativePath:"faq/README.md",key:"v-40b685e4",path:"/faq/",headers:[{level:3,title:"I don't know where to start 😥",slug:"i-don-t-know-where-to-start-😥"},{level:3,title:"I'm getting a compilation error saying a Schema is missing, but I don't know which one.",slug:"i-m-getting-a-compilation-error-saying-a-schema-is-missing-but-i-don-t-know-which-one"},{level:3,title:"I want to use Caliban, but I use Cats Effect / Monix instead of ZIO.",slug:"i-want-to-use-caliban-but-i-use-cats-effect-monix-instead-of-zio"},{level:3,title:'My query fails with an "Effect failure" error. How can I get more details?',slug:"my-query-fails-with-an-effect-failure-error-how-can-i-get-more-details"},{level:3,title:"I have more than 22 fields in my Query, I can't create a case class for it.",slug:"i-have-more-than-22-fields-in-my-query-i-can-t-create-a-case-class-for-it"},{level:3,title:"How to deal with authentication/authorization?",slug:"how-to-deal-with-authentication-authorization"},{level:3,title:"I have 2 case classes with the same name (different packages). How to avoid conflicts?",slug:"i-have-2-case-classes-with-the-same-name-different-packages-how-to-avoid-conflicts"},{level:3,title:"The auto-generated schema shows a field is nullable, but I want it non-nullable instead.",slug:"the-auto-generated-schema-shows-a-field-is-nullable-but-i-want-it-non-nullable-instead"},{level:3,title:"Can I use a union as input?",slug:"can-i-use-a-union-as-input"},{level:3,title:"How to deal with recursive types?",slug:"how-to-deal-with-recursive-types"},{level:3,title:'I\'m getting a "Method too large" compiler error.',slug:"i-m-getting-a-method-too-large-compiler-error"},{level:3,title:"How can I define a Schema for a Java enum?",slug:"how-can-i-define-a-schema-for-a-java-enum"},{level:3,title:"I don't want to use Throwable as my error type",slug:"i-don-t-want-to-use-throwable-as-my-error-type"},{level:3,title:"My interface is missing from the schema",slug:"my-interface-is-missing-from-the-schema"}]},{title:"Resources",frontmatter:{},regularPath:"/resources/",relativePath:"resources/README.md",key:"v-a971ed74",path:"/resources/",headers:[{level:2,title:"Talks",slug:"talks"},{level:2,title:"Blog Articles",slug:"blog-articles"},{level:2,title:"Related Projects",slug:"related-projects"}]}],themeConfig:{logo:"/caliban.svg",locales:{"/":{selectText:"Language",label:"English",nav:[{text:"Documentation",link:"/docs/"},{text:"Resources",link:"/resources/"},{text:"FAQ",link:"/faq/"},{text:"About",link:"/about/"},{text:"Github",link:"https://github.com/ghostdogpr/caliban"},{text:"Scaladoc",link:"https://javadoc.io/doc/com.github.ghostdogpr/caliban_2.12/"}],sidebar:{"/docs/":[{title:"Caliban Server",collapsable:!0,sidebarDepth:2,children:["","schema","middleware","optimization","validation","introspection","adapters","interop","federation","relay-connections","schema-reporting","server-codegen"]},{title:"Caliban Client",collapsable:!0,sidebarDepth:2,children:["client","client-codegen","laminext"]},{title:"Caliban Tools",collapsable:!0,sidebarDepth:2,children:["tools","stitching","schema-comparison"]},{title:"Examples",path:"examples"}]}}}},locales:{"/":{lang:"en-US",title:"Caliban",description:"Functional GraphQL library for Scala",path:"/"}}};n(234);Wn.component("Badge",()=>Promise.all([n.e(0),n.e(4)]).then(n.bind(null,302))),Wn.component("CodeBlock",()=>Promise.all([n.e(0),n.e(5)]).then(n.bind(null,298))),Wn.component("CodeGroup",()=>Promise.all([n.e(0),n.e(6)]).then(n.bind(null,299)));n(235);var As=[{},({Vue:t})=>{t.mixin({computed:{$dataBlock(){return this.$options.__data__block__}}})},{},{}],Ts=[];class Ls extends class{constructor(){this.store=new Wn({data:{state:{}}})}$get(t){return this.store.state[t]}$set(t,e){Wn.set(this.store.state,t,e)}$emit(...t){this.store.$emit(...t)}$on(...t){this.store.$on(...t)}}{}Object.assign(Ls.prototype,{getPageAsyncComponent:as,getLayoutAsyncComponent:ss,getAsyncComponent:cs,getVueComponent:us});var Rs={install(t){const e=new Ls;t.$vuepress=e,t.prototype.$vuepress=e}};function Is(t,e){const n=e.toLowerCase();return t.options.routes.some(t=>t.path.toLowerCase()===n)}var Ms={props:{pageKey:String,slotKey:{type:String,default:"default"}},render(t){const e=this.pageKey||this.$parent.$page.key;return fs("pageKey",e),Wn.component(e)||Wn.component(e,as(e)),Wn.component(e)?t(e):t("")}},Ds={functional:!0,props:{slotKey:String,required:!0},render:(t,{props:e,slots:n})=>t("div",{class:["content__"+e.slotKey]},n()[e.slotKey])},Ns={computed:{openInNewWindowTitle(){return this.$themeLocaleConfig.openNewWindowText||"(opens new window)"}}},zs=(n(236),n(237),Object(Ss.a)(Ns,(function(){var t=this._self._c;return t("span",[t("svg",{staticClass:"icon outbound",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"}},[t("path",{attrs:{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}}),this._v(" "),t("polygon",{attrs:{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"}})]),this._v(" "),t("span",{staticClass:"sr-only"},[this._v(this._s(this.openInNewWindowTitle))])])}),[],!1,null,null,null).exports),Fs={functional:!0,render(t,{parent:e,children:n}){if(e._isMounted)return n;e.$once("hook:mounted",()=>{e.$forceUpdate()})}};Wn.config.productionTip=!1,Wn.use(Va),Wn.use(Rs),Wn.mixin(function(t,e,n=Wn){!function(t){t.locales&&Object.keys(t.locales).forEach(e=>{t.locales[e].path=e});Object.freeze(t)}(e),n.$vuepress.$set("siteData",e);const r=new(t(n.$vuepress.$get("siteData"))),o=Object.getOwnPropertyDescriptors(Object.getPrototypeOf(r)),i={};return Object.keys(o).reduce((t,e)=>(e.startsWith("$")&&(t[e]=o[e].get),t),i),{computed:i}}(t=>class{setPage(t){this.__page=t}get $site(){return t}get $themeConfig(){return this.$site.themeConfig}get $frontmatter(){return this.$page.frontmatter}get $localeConfig(){const{locales:t={}}=this.$site;let e,n;for(const r in t)"/"===r?n=t[r]:0===this.$page.path.indexOf(r)&&(e=t[r]);return e||n||{}}get $siteTitle(){return this.$localeConfig.title||this.$site.title||""}get $canonicalUrl(){const{canonicalUrl:t}=this.$page.frontmatter;return"string"==typeof t&&t}get $title(){const t=this.$page,{metaTitle:e}=this.$page.frontmatter;if("string"==typeof e)return e;const n=this.$siteTitle,r=t.frontmatter.home?null:t.frontmatter.title||t.title;return n?r?r+" | "+n:n:r||"VuePress"}get $description(){const t=function(t){if(t){const e=t.filter(t=>"description"===t.name)[0];if(e)return e.content}}(this.$page.frontmatter.meta);return t||(this.$page.frontmatter.description||this.$localeConfig.description||this.$site.description||"")}get $lang(){return this.$page.frontmatter.lang||this.$localeConfig.lang||"en-US"}get $localePath(){return this.$localeConfig.path||"/"}get $themeLocaleConfig(){return(this.$site.themeConfig.locales||{})[this.$localePath]||{}}get $page(){return this.__page?this.__page:function(t,e){for(let n=0;nn||(t.hash?!Wn.$vuepress.$get("disableScrollBehavior")&&{selector:decodeURIComponent(t.hash)}:{x:0,y:0})});!function(t){t.beforeEach((e,n,r)=>{if(Is(t,e.path))r();else if(/(\/|\.html)$/.test(e.path))if(/\/$/.test(e.path)){const n=e.path.replace(/\/$/,"")+".html";Is(t,n)?r(n):r()}else r();else{const n=e.path+"/",o=e.path+".html";Is(t,o)?r(o):Is(t,n)?r(n):r()}})}(n);const r={};try{await Promise.all(As.filter(t=>"function"==typeof t).map(e=>e({Vue:Wn,options:r,router:n,siteData:Ps,isServer:t})))}catch(t){console.error(t)}return{app:new Wn(Object.assign(r,{router:n,render:t=>t("div",{attrs:{id:"app"}},[t("RouterView",{ref:"layout"}),t("div",{class:"global-ui"},Ts.map(e=>t(e)))])})),router:n}}(!1).then(({app:t,router:e})=>{e.onReady(()=>{t.$mount("#app")})})}]); \ No newline at end of file diff --git a/docs/docs/adapters.html b/docs/docs/adapters.html index f2d61e78a2..57d0f25a85 100644 --- a/docs/docs/adapters.html +++ b/docs/docs/adapters.html @@ -8,7 +8,7 @@ - + @@ -110,6 +110,6 @@ →

- + diff --git a/docs/docs/client-codegen.html b/docs/docs/client-codegen.html index bcaecc96ee..8df3a658f4 100644 --- a/docs/docs/client-codegen.html +++ b/docs/docs/client-codegen.html @@ -8,7 +8,7 @@ - + @@ -140,6 +140,6 @@ →

- + diff --git a/docs/docs/client.html b/docs/docs/client.html index 03c3bbb2af..55ab7d9a25 100644 --- a/docs/docs/client.html +++ b/docs/docs/client.html @@ -8,7 +8,7 @@ - + @@ -101,6 +101,6 @@ →

- + diff --git a/docs/docs/examples.html b/docs/docs/examples.html index c850788fa5..cfb0b50122 100644 --- a/docs/docs/examples.html +++ b/docs/docs/examples.html @@ -8,7 +8,7 @@ - + @@ -41,6 +41,6 @@

- + diff --git a/docs/docs/federation.html b/docs/docs/federation.html index a869bed306..4136e32ba5 100644 --- a/docs/docs/federation.html +++ b/docs/docs/federation.html @@ -8,7 +8,7 @@ - + @@ -105,6 +105,6 @@ →

- + diff --git a/docs/docs/index.html b/docs/docs/index.html index 048ba3f257..e187bbfc2b 100644 --- a/docs/docs/index.html +++ b/docs/docs/index.html @@ -8,7 +8,7 @@ - + @@ -36,7 +36,7 @@ Github (opens new window)

# Getting Started

Caliban is a purely functional library for creating GraphQL servers and clients in Scala.

For more details on Caliban Client, see the dedicated section. The rest of this page is about the backend part of the library.

The design principles of Caliban are the following:

# A simple example

First, add the following dependency to your build.sbt file:

"com.github.ghostdogpr" %% "caliban" % "2.4.3"
+   (opens new window)

# Getting Started

Caliban is a purely functional library for creating GraphQL servers and clients in Scala.

For more details on Caliban Client, see the dedicated section. The rest of this page is about the backend part of the library.

The design principles of Caliban are the following:

# A simple example

First, add the following dependency to your build.sbt file:

"com.github.ghostdogpr" %% "caliban" % "2.4.3"
 

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.

Let's say we have a class Character and 2 functions: getCharacters and getCharacter:

case class Character(name: String, age: Int)
 
 def getCharacters: List[Character] = Nil
@@ -129,6 +129,6 @@
       
       →
     

- + diff --git a/docs/docs/interop.html b/docs/docs/interop.html index bd087bd335..7ee76a6d6a 100644 --- a/docs/docs/interop.html +++ b/docs/docs/interop.html @@ -8,7 +8,7 @@ - + @@ -244,6 +244,6 @@ →

- + diff --git a/docs/docs/introspection.html b/docs/docs/introspection.html index 7bfe2d34ad..0efffea057 100644 --- a/docs/docs/introspection.html +++ b/docs/docs/introspection.html @@ -8,7 +8,7 @@ - + @@ -45,6 +45,6 @@ →

- + diff --git a/docs/docs/laminext.html b/docs/docs/laminext.html index faf9c34e83..7cb9c19e7f 100644 --- a/docs/docs/laminext.html +++ b/docs/docs/laminext.html @@ -8,7 +8,7 @@ - + @@ -69,6 +69,6 @@ →

- + diff --git a/docs/docs/middleware.html b/docs/docs/middleware.html index 23a8d7a949..f2319c4dc5 100644 --- a/docs/docs/middleware.html +++ b/docs/docs/middleware.html @@ -8,7 +8,7 @@ - + @@ -192,6 +192,6 @@ →

- + diff --git a/docs/docs/optimization.html b/docs/docs/optimization.html index 408c728efc..a6295c0f62 100644 --- a/docs/docs/optimization.html +++ b/docs/docs/optimization.html @@ -8,7 +8,7 @@ - + @@ -162,6 +162,6 @@ →

- + diff --git a/docs/docs/relay-connections.html b/docs/docs/relay-connections.html index 6b2f5d3b17..ae3440fef8 100644 --- a/docs/docs/relay-connections.html +++ b/docs/docs/relay-connections.html @@ -8,7 +8,7 @@ - + @@ -142,6 +142,6 @@ →

- + diff --git a/docs/docs/schema-comparison.html b/docs/docs/schema-comparison.html index ad7583dd96..78d69993e1 100644 --- a/docs/docs/schema-comparison.html +++ b/docs/docs/schema-comparison.html @@ -8,7 +8,7 @@ - + @@ -75,6 +75,6 @@ →

- + diff --git a/docs/docs/schema-reporting.html b/docs/docs/schema-reporting.html index 0e04133ebd..6d04c6435d 100644 --- a/docs/docs/schema-reporting.html +++ b/docs/docs/schema-reporting.html @@ -8,7 +8,7 @@ - + @@ -70,6 +70,6 @@ →

- + diff --git a/docs/docs/schema.html b/docs/docs/schema.html index 3fc508fa02..47bbdc9ddd 100644 --- a/docs/docs/schema.html +++ b/docs/docs/schema.html @@ -8,7 +8,7 @@ - + @@ -198,6 +198,6 @@ →

- + diff --git a/docs/docs/server-codegen.html b/docs/docs/server-codegen.html index 42f6f1d65d..2cfd6cc4bf 100644 --- a/docs/docs/server-codegen.html +++ b/docs/docs/server-codegen.html @@ -8,7 +8,7 @@ - + @@ -80,6 +80,6 @@ →

- + diff --git a/docs/docs/stitching.html b/docs/docs/stitching.html index b2424dc113..42d78c9993 100644 --- a/docs/docs/stitching.html +++ b/docs/docs/stitching.html @@ -8,7 +8,7 @@ - + @@ -181,6 +181,6 @@ →

- + diff --git a/docs/docs/tools.html b/docs/docs/tools.html index 2c945582fe..49008751a6 100644 --- a/docs/docs/tools.html +++ b/docs/docs/tools.html @@ -8,7 +8,7 @@ - + @@ -46,6 +46,6 @@ →

- + diff --git a/docs/docs/validation.html b/docs/docs/validation.html index 064878835f..a0a453b3f1 100644 --- a/docs/docs/validation.html +++ b/docs/docs/validation.html @@ -8,7 +8,7 @@ - + @@ -54,6 +54,6 @@ →

- + diff --git a/docs/faq/index.html b/docs/faq/index.html index 89ce8c79f3..f38b5674b5 100644 --- a/docs/faq/index.html +++ b/docs/faq/index.html @@ -8,7 +8,7 @@ - + @@ -74,6 +74,6 @@ val api = graphQL(RootResolver(Query(A("a"), B("b")))).withAdditionalTypes(List(interfaceType))
- + diff --git a/docs/index.html b/docs/index.html index 1517b73785..a383429aab 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,7 +8,7 @@ - + @@ -42,7 +42,7 @@ Functional GraphQL library for Scala

Get Started → -

Purely functional

All interfaces are pure and types are referentially transparent. Schemas are type safe and derived at compile time.

Minimal boilerplate

No need to manually define a schema for every type in your API. Let the compiler do the boring work.

Excellent interoperability

Out-of-the-box support for major HTTP server libraries, effect types, Json libraries and more.

- +

High performance

While every public interface is pure and immutable, library internals have been optimized for speed.

Minimal boilerplate

No need to manually define a schema for every type in your API. Let the compiler do the boring work.

Excellent interoperability

Out-of-the-box support for major HTTP server libraries, effect types, Json libraries and more.

+ diff --git a/docs/resources/index.html b/docs/resources/index.html index b92471d5f3..0754db4c7e 100644 --- a/docs/resources/index.html +++ b/docs/resources/index.html @@ -8,7 +8,7 @@ - + @@ -38,6 +38,6 @@ Scaladoc (opens new window)

# Resources

# Talks

# Blog Articles

- +