Skip to content

Commit

Permalink
Merge pull request #279 from oskargotte/main
Browse files Browse the repository at this point in the history
Support federation v2.3
  • Loading branch information
yanns authored Nov 11, 2023
2 parents d2a0a5d + 4c25216 commit 9ab988d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
14 changes: 13 additions & 1 deletion core/src/main/scala/sangria/federation/v2/Directives.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ object Directives {
)
}

/** [@interfaceObject](https://www.apollographql.com/docs/federation/federated-types/federated-directives/#interfaceobject)
* directive definition
*/
val InterfaceObjectDefinition: Directive =
Directive(name = "interfaceObject", locations = Set(DirectiveLocation.Object))

/** [@extends](https://www.apollographql.com/docs/federation/federated-types/federated-directives#interfaceobject)
* directive
*/
val InterfaceObject: ast.Directive = ast.Directive(name = "interfaceObject")

/** [@extends](https://www.apollographql.com/docs/federation/federated-types/federated-directives#extends)
* directive definition
*/
Expand All @@ -89,7 +100,8 @@ object Directives {
*/
val ShareableDefinition: Directive = Directive(
name = "shareable",
locations = Set(DirectiveLocation.Object, DirectiveLocation.FieldDefinition)
locations = Set(DirectiveLocation.Object, DirectiveLocation.FieldDefinition),
repeatable = true
)

/** [@shareable](https://www.apollographql.com/docs/federation/federated-types/federated-directives#shareable)
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/scala/sangria/federation/v2/Federation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ object Federation {

val federationDirectives: List[Directive] = List(
Directives.Key.definition,
Directives.InterfaceObjectDefinition,
Directives.ExtendsDefinition,
Directives.ShareableDefinition,
Directives.InaccessibleDefinition,
Expand All @@ -95,7 +96,7 @@ object Federation {
federationDirectives

val federationV2Link = Directives.Link(
url = "https://specs.apollo.dev/federation/v2.1",
url = "https://specs.apollo.dev/federation/v2.3",
`import` = Some(importedDirectives.map(d => Link__Import("@" + d.name)).toVector)
)

Expand Down
2 changes: 1 addition & 1 deletion core/src/test/scala/sangria/federation/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import sangria.schema.SchemaChange.AbstractChange

package object federation {

val spec: String = "https://specs.apollo.dev/federation/v2.1"
val spec: String = "https://specs.apollo.dev/federation/v2.3"

def beCompatibleWith(expectedSchema: Schema[_, _]): Matcher[Schema[_, _]] =
Matcher { schema: Schema[_, _] =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ class DirectivesSpec extends AnyWordSpec {
renderLike("""@key(fields: "id", resolvable: false)""")
}

"support @interfaceObject directive" in {
// https://www.apollographql.com/docs/federation/federated-types/federated-directives#interfaceobject
Directives.InterfaceObject must renderLike("@interfaceObject")
}

"support @extends directive" in {
// https://www.apollographql.com/docs/federation/federated-types/federated-directives#extends
Directives.Extends must renderLike("@extends")
Expand Down
18 changes: 11 additions & 7 deletions core/src/test/scala/sangria/federation/v2/FederationSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class FederationSpec extends AsyncFreeSpec {

val expectedSubGraphSchema = Schema
.buildFromAst(graphql"""
schema @link(url: "https://specs.apollo.dev/federation/v2.1", import: ["@key", "@extends", "@shareable", "@inaccessible", "@override", "@external", "@provides", "@requires", "@tag"]) {
schema @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@key", "@interfaceObject", "@extends", "@shareable", "@inaccessible", "@override", "@external", "@provides", "@requires", "@tag"]) {
query: Query
}

Expand All @@ -61,6 +61,8 @@ class FederationSpec extends AsyncFreeSpec {
sdl: String
}

directive @interfaceObject on OBJECT

directive @extends on INTERFACE | OBJECT

directive @external on FIELD_DEFINITION
Expand All @@ -73,7 +75,7 @@ class FederationSpec extends AsyncFreeSpec {

directive @link(url: String!, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA

directive @shareable on OBJECT | FIELD_DEFINITION
directive @shareable repeatable on OBJECT | FIELD_DEFINITION

directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION

Expand Down Expand Up @@ -110,7 +112,7 @@ class FederationSpec extends AsyncFreeSpec {

val expectedSubGraphSchema = Schema
.buildFromAst(graphql"""
schema @link(url: "https://specs.apollo.dev/federation/v2.1", import: ["@key", "@extends", "@shareable", "@inaccessible", "@override", "@external", "@provides", "@requires", "@tag"]) {
schema @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@key", "@interfaceObject", "@extends", "@shareable", "@inaccessible", "@override", "@external", "@provides", "@requires", "@tag"]) {
query: Query
}

Expand Down Expand Up @@ -145,6 +147,8 @@ class FederationSpec extends AsyncFreeSpec {
sdl: String
}

directive @interfaceObject on OBJECT

directive @extends on INTERFACE | OBJECT

directive @external on FIELD_DEFINITION
Expand All @@ -157,7 +161,7 @@ class FederationSpec extends AsyncFreeSpec {

directive @link(url: String!, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA

directive @shareable on OBJECT | FIELD_DEFINITION
directive @shareable repeatable on OBJECT | FIELD_DEFINITION

directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION

Expand Down Expand Up @@ -203,7 +207,7 @@ class FederationSpec extends AsyncFreeSpec {
.map(QueryRenderer.renderPretty(_) should be("""{
| data: {
| _service: {
| sdl: "schema @link(url: \"https://specs.apollo.dev/federation/v2.1\", import: [\"@key\", \"@extends\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@tag\"]) {\n query: Query\n}\n\ntype Query {\n field: Int\n}"
| sdl: "schema @link(url: \"https://specs.apollo.dev/federation/v2.3\", import: [\"@key\", \"@interfaceObject\", \"@extends\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@tag\"]) {\n query: Query\n}\n\ntype Query {\n field: Int\n}"
| }
| }
|}""".stripMargin))
Expand Down Expand Up @@ -233,7 +237,7 @@ class FederationSpec extends AsyncFreeSpec {
.map(QueryRenderer.renderPretty(_) should be("""{
| data: {
| _service: {
| sdl: "schema @link(url: \"https://specs.apollo.dev/federation/v2.1\", import: [\"@key\", \"@extends\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@tag\"]) {\n query: Query\n}\n\ntype Query {\n states: [State]\n}\n\ntype State @key(fields: \"id\") {\n id: Int\n value: String\n}"
| sdl: "schema @link(url: \"https://specs.apollo.dev/federation/v2.3\", import: [\"@key\", \"@interfaceObject\", \"@extends\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@tag\"]) {\n query: Query\n}\n\ntype Query {\n states: [State]\n}\n\ntype State @key(fields: \"id\") {\n id: Int\n value: String\n}"
| }
| }
|}""".stripMargin))
Expand All @@ -260,7 +264,7 @@ class FederationSpec extends AsyncFreeSpec {
.map(QueryRenderer.renderPretty(_) should be("""{
| data: {
| _service: {
| sdl: "schema @link(url: \"https://specs.apollo.dev/federation/v2.1\", import: [\"@key\", \"@extends\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@tag\"]) {\n query: Query\n}\n\n\"The `Long` scalar type represents non-fractional signed whole numeric values. Long can represent values between -(2^63) and 2^63 - 1.\"\nscalar Long\n\ntype Query {\n foo: Long\n bar: Int\n}"
| sdl: "schema @link(url: \"https://specs.apollo.dev/federation/v2.3\", import: [\"@key\", \"@interfaceObject\", \"@extends\", \"@shareable\", \"@inaccessible\", \"@override\", \"@external\", \"@provides\", \"@requires\", \"@tag\"]) {\n query: Query\n}\n\n\"The `Long` scalar type represents non-fractional signed whole numeric values. Long can represent values between -(2^63) and 2^63 - 1.\"\nscalar Long\n\ntype Query {\n foo: Long\n bar: Int\n}"
| }
| }
|}""".stripMargin))
Expand Down

0 comments on commit 9ab988d

Please sign in to comment.