Skip to content

Commit

Permalink
add federation 2.6 support, update gateway dependencies (#2043)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulpdaniels authored Dec 17, 2023
1 parent 81d9b9d commit 9dd2287
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 81 deletions.
13 changes: 8 additions & 5 deletions examples/src/main/resources/gateway_v2/gateway.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const {ApolloServer} = require('apollo-server');
const {ApolloServerPluginInlineTrace} = require('apollo-server-core')
const {ApolloGateway, IntrospectAndCompose} = require('@apollo/gateway');
import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginInlineTrace } from '@apollo/server/plugin/inlineTrace'
import { ApolloGateway, IntrospectAndCompose } from '@apollo/gateway';
import {startStandaloneServer} from "@apollo/server/standalone";

const gateway = new ApolloGateway({
supergraphSdl: new IntrospectAndCompose({
Expand All @@ -21,7 +22,9 @@ const gateway = new ApolloGateway({
]
});

server.listen().then(({url}) => {
console.log(`🚀 Server ready at ${url}`)
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 }
})

console.log(`🚀 Server ready at ${url}`)
})();
7 changes: 4 additions & 3 deletions examples/src/main/resources/gateway_v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
"name": "federated-gateway",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "gateway.js",
"scripts": {
"start": "node gateway.js"
},
"keywords": [],
"license": "MIT",
"dependencies": {
"apollo-server": "3.6.7",
"@apollo/gateway": "2.0.1",
"graphql": "16.3.0"
"@apollo/server": "4.9.5",
"@apollo/gateway": "2.6.2",
"graphql": "16.8.1"
}
}
74 changes: 9 additions & 65 deletions examples/src/main/scala/example/federation/FederatedApp.scala
Original file line number Diff line number Diff line change
@@ -1,75 +1,19 @@
package example.federation

import caliban.quick._
import example.federation.FederationData.characters.sampleCharacters
import example.federation.FederationData.episodes.sampleEpisodes
import caliban.Http4sAdapter
import caliban.interop.tapir.HttpInterpreter
import cats.data.Kleisli
import com.comcast.ip4s._
import fs2.io.net.Network
import org.http4s.StaticFile
import org.http4s.implicits._
import org.http4s.server.Router
import org.http4s.ember.server.EmberServerBuilder
import org.http4s.server.middleware.CORS
import zio._
import zio.interop.catz._

object FederatedApp extends CatsApp {
import sttp.tapir.json.circe._
object FederatedApp extends ZIOAppDefault {

type ExampleTask[A] = RIO[Any, A]

private implicit val network: Network[ExampleTask] = Network.forAsync

val service1 =
CharacterService
.make(sampleCharacters)
.memoize
.flatMap(layer =>
for {
interpreter <- FederatedApi.Characters.api.interpreter.map(_.provideLayer(layer))
_ <- EmberServerBuilder
.default[ExampleTask]
.withHost(host"localhost")
.withPort(port"8089")
.withHttpApp(
Router[ExampleTask](
"/api/graphql" -> CORS.policy(Http4sAdapter.makeHttpService(HttpInterpreter(interpreter))),
"/graphiql" -> Kleisli.liftF(StaticFile.fromResource("/graphiql.html", None))
).orNotFound
)
.build
.toScopedZIO
_ <- Console.printLine("Server online at http://localhost:8089/\nPress RETURN to stop...")
_ <- Console.readLine
} yield ()
)

val service2 =
EpisodeService
.make(sampleEpisodes)
.memoize
.flatMap(layer =>
for {
interpreter <- FederatedApi.Episodes.api.interpreter.map(_.provideLayer(layer))
_ <- EmberServerBuilder
.default[ExampleTask]
.withHost(host"localhost")
.withPort(port"8088")
.withHttpApp(
Router[ExampleTask](
"/api/graphql" -> CORS.policy(Http4sAdapter.makeHttpService(HttpInterpreter(interpreter))),
"/graphiql" -> Kleisli.liftF(StaticFile.fromResource("/graphiql.html", None))
).orNotFound
)
.build
.toScopedZIO
_ <- Console.printLine("Server online at http://localhost:8088/\nPress RETURN to stop...")
_ <- Console.readLine
} yield ()
)
val episodesApi = FederatedApi.Episodes.api.runServer(8089, "/api/graphql", Some("/graphiql"))
val charactersApi = FederatedApi.Characters.api.runServer(8088, "/api/graphql", Some("/graphiql"))

override def run =
(service1 race service2).exitCode
(episodesApi zipPar charactersApi)
.provide(
EpisodeService.make(sampleEpisodes),
CharacterService.make(sampleCharacters)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package example.federation.v2
import caliban._
import caliban.federation.EntityResolver
import caliban.federation.tracing.ApolloFederatedTracing
import caliban.federation.v2_0.{ federated, GQLKey }
import caliban.federation.v2_6.{ federated, GQLKey }
import caliban.schema.Annotations.{ GQLDeprecated, GQLDescription }
import caliban.schema.{ ArgBuilder, GenericSchema, Schema }
import caliban.schema.ArgBuilder.auto._
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package example.federation.v2

import caliban.federation.v2_0._
import caliban.federation.v2_6._
import zio.query.ZQuery

object FederationData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,10 @@ abstract class FederationSupport(
* @param value a value of type `T`
*/
override def resolve(value: _Entity): Step[R] =
QueryStep(
_entityMap
.get(value.__typename)
.fold[ZQuery[R, CalibanError, Step[R]]](ZQuery.succeed(Step.NullStep))(_.resolve(value.value))
)
_entityMap
.get(value.__typename)
.fold[Step[R]](Step.NullStep)(resolver => QueryStep(resolver.resolve(value.value)))

}

case class Query(
Expand Down
9 changes: 8 additions & 1 deletion federation/src/main/scala/caliban/federation/package.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package caliban

import caliban.federation.v2x.{ FederationDirectivesV2_3, FederationDirectivesV2_5, FederationV2, Versions }
import caliban.federation.v2x.{
FederationDirectivesV2_3,
FederationDirectivesV2_5,
FederationDirectivesV2_6,
FederationV2,
Versions
}

package object federation {

Expand All @@ -10,5 +16,6 @@ package object federation {
lazy val v2_3 = new FederationV2(List(Versions.v2_3)) with FederationDirectivesV2_3
lazy val v2_4 = new FederationV2(List(Versions.v2_4)) with FederationDirectivesV2_3
lazy val v2_5 = new FederationV2(List(Versions.v2_5)) with FederationDirectivesV2_5
lazy val v2_6 = new FederationV2(List(Versions.v2_6)) with FederationDirectivesV2_6

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package caliban.federation.v2x

import caliban.InputValue.ListValue
import caliban.Value.StringValue
import caliban.parsing.adt.Directive
import caliban.schema.Annotations.GQLDirective

trait FederationDirectivesV2_6 extends FederationDirectivesV2_5 {

def Policy(policies: List[List[String]]) =
Directive("policy", Map("policies" -> ListValue(policies.map(s => ListValue(s.map(s => StringValue(s)))))))

case class GQLPolicy(policies: List[List[String]]) extends GQLDirective(Policy(policies))

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ object FederationV2 {
`import` = v2_4.`import` :+ Import("@authenticated") :+ Import("@requiresScopes")
)

private[v2x] val v2_6 = Link(
url = s"$federationV2Url/v2.6",
`import` = v2_5.`import` :+ Import("@policy")
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ object Versions {
val v2_3 = FederationV2.v2_3
val v2_4 = FederationV2.v2_4
val v2_5 = FederationV2.v2_5
val v2_6 = FederationV2.v2_6

}

0 comments on commit 9dd2287

Please sign in to comment.