github ghostdogpr/caliban v2.1.0

latest releases: v2.8.1, v2.8.0, v2.7.2...
18 months ago

Release Notes

This release is packed with features, improvements and fixes. In fact, it is probably the single most important release since Caliban Client was added. It contains several breaking changes, so make to read what follows before upgrading!

Schema derivation

One of the most requested features of Caliban was the ability to opt out from the automatic schema derivation and use a semi-automatic approach where you have to create a schema for each individual type. Automatic schema derivation is convenient when you get started, but can quickly becoming a pain when you have large schemas: slow compilation, large amount of generated code, difficulty finding which types require a custom instance or even knowing which instance is actually used.

We decided to make automatic generation optional using an import. Without this import, you will need to provide an implicit/given schema for each type that is not already supported. We also added support for the derives keyword in Scala 3, so that it's super easy to create schemas with the least amount of boilerplate.

Here is how derivation work with Scala 3:

// semi-auto derivation, needs a Schema for inner types
final case class Foo(value: String) derives Schema.SemiAuto

// semi-auto derivation when R in Schema[R, A] is not Any
object CustomSchema extends SchemaDerivation[MyEnv]
final case class Foo(value: String) derives CustomSchema.SemiAuto

// semi-auto derivation without the derives keyword
given Schema[MyEnv, Foo] = Schema.gen

// auto derivation
import Schema.auto._
given Schema[MyEnv, Foo] = genAll

Here's how it looks with Scala 2 (also cross-compile with Scala 3):

// semi-auto derivation, needs Schema for inner types
implicit val fooSchema: Schema[Any, Foo] = Schema.gen

// auto derivation, generates a Schema for inner types
import Schema.auto._
implicit val fooSchema: Schema[Any, Foo] = genAll

// semi-auto derivation when R in Schema[R, A] is not Any
object schema extends GenericSchema[MyEnv]
implicit val fooSchema: Schema[MyEnv, Foo] = schema.gen

// auto derivation when R in Schema[R, A] is not Any
object schema extends GenericSchema[MyEnv]
import schema.auto._
implicit val fooSchema: Schema[MyEnv, Foo] = genAll

Note that ArgBuilder derivation follows the same pattern (without the R part) and requires an import if you want auto generation.

This change was done in #1591 by @ghostdogpr

Adapters and Json libraries

Historically each adapter was tied to a specific Json library: for example Circe was used for http4s and zio-http, while play-json was the default for play. As we recently introduced support for jsoniter-scala, we found it was quite inconvenient to use it with the existing adapters. So we decided to make the adapters completely free of any Json dependency, so you can use the Json library you want!

All you have to do is adding one of these Tapir dependencies:

"com.softwaremill.sttp.tapir" %% "tapir-json-circe"     % "1.2.11" // Circe
"com.softwaremill.sttp.tapir" %% "tapir-jsoniter-scala" % "1.2.11" // Jsoniter
"com.softwaremill.sttp.tapir" %% "tapir-json-play"      % "1.2.11" // Play JSON
"com.softwaremill.sttp.tapir" %% "tapir-json-zio"       % "1.2.11" // ZIO JSON

And then later in your code (you only need one!):

import sttp.tapir.json.circe._
import sttp.tapir.json.jsoniter._
import sttp.tapir.json.play._
import sttp.tapir.json.zio._

This change was done in #1552 by @kyri-petrou

Performance improvements

Performance was improved in almost every parts of Caliban: from parsing to validation to execution. Even Caliban Client received some love! Here are the details:

  • Used the Fastparse parser on Scala 3, which makes parsing much faster and removes code duplication (previously Fastparse was used for Scala 2 and cats-parse for Scala 3) #1646 by @kyri-petrou
  • Used ZPure instead of ZIO for validation logic, which improves validation performance greatly #1633 by @paulpdaniels
  • Added multiple execution performance improvements in particular with fragments #1635 #1643 #1650 by @kyri-petrou
  • Switched the internal JSON library used in Caliban Client from Circe to Jsoniter-scala for a better runtime performance #1639 by @paulpdaniels

Other changes

Server

  • Moved the graphQL function directly to the caliban package (the old one is still there but deprecated) by @ghostdogpr
  • Added new wrappers for observability #1616 by @frekw
    • Wrappers.logSlowQueries for logging slow queries with ZIO.logWarning
    • Wrappers.metrics for gathering metrics about query execution
    • TracingWrapper.traced for creating traces with OpenTelemetry (in a separate dependency caliban-tracing)
  • Reduced the size of the code generated by derivation (Scala 3 only) #1607 by @kyri-petrou
  • Stopped adding the suffix Input to input objects that already have that suffix #1471 by @brodin
  • Prevented validation error when an input field is null but a default value exists #1629 by @ghostdogpr
  • Stopped requiring a Schema for fields annotated with @GQLExcluded (Scala 3 only) #1630 by @kyri-petrou
  • Added support for repeatable directives #1617 by @jgulotta
  • Added the ability to skip query validation in wrappers (used in ApolloPersistedQueries wrapper) #1557 by @kyri-petrou
  • Fixed rendering of directive arguments that contain special characters #1656 by @camarena
  • Added isIntrospection field on Document #1662 by @kyri-petrou
  • Fixed the Monix interop that had been broken by an older release #1628 by @ghostdogpr

Adapters

  • Upgraded zio-http dependency to 0.0.5 (this is using the new organization) #1521 by @frekw

Federation

Tools

Don't miss a new caliban release

NewReleases is sending notifications on new releases.