Skip to content

Commit df51b2b

Browse files
authored
easier directives for sangria (#250)
1 parent 947aa15 commit df51b2b

File tree

6 files changed

+51
-125
lines changed

6 files changed

+51
-125
lines changed

implementations/sangria/README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,24 @@
22

33
Implementation of a federated subgraph based on the scala library [sangria](https://sangria-graphql.github.io/).
44

5+
## Practical information
56

6-
# Usage
7+
There are several ways to define a GraphQL schema with sangria.
8+
Here we are using a code first schema generation.
9+
And we are splitting the domain model and the GraphQL schema. This ensures separation of concerns.
710

8-
## Starting the GraphQL server
11+
On the other hand, this approach needs more lines of code.
12+
If your goal is to have less lines of code, you could mix the domain and the GraphQL and use the [automatic derivation](https://sangria-graphql.github.io/learn/#macro-based-graphql-type-derivation).
13+
14+
## Usage
15+
16+
### Starting the GraphQL server
917

1018
```
1119
sbt run
1220
```
1321

14-
## Printing the GraphQL schema (SQL)
22+
### Printing the GraphQL schema (SQL)
1523

1624
```
1725
sbt "run printSchema"

implementations/sangria/build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import sbt._
22

33
version := "1.0.0"
4-
scalaVersion := "2.13.9"
4+
scalaVersion := "2.13.10"
55

66
val http4sVersion = "1.0.0-M37"
77
val circeVersion = "0.14.3"
88

99
libraryDependencies ++= List(
10-
"org.sangria-graphql" %% "sangria-federated" % "0.4.0",
10+
"org.sangria-graphql" %% "sangria-federated" % "0.5.0",
1111
"org.sangria-graphql" %% "sangria-circe" % "1.3.2",
1212
"org.http4s" %% "http4s-ember-server" % http4sVersion,
1313
"org.http4s" %% "http4s-dsl" % http4sVersion,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.6.2
1+
sbt.version=1.7.2

implementations/sangria/src/main/scala/graphql/Directives.scala

Lines changed: 0 additions & 84 deletions
This file was deleted.

implementations/sangria/src/main/scala/graphql/ProductGraphQLSchema.scala

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package graphql
22

3-
import graphql.Directives.{Inaccessible, Provides, Shareable, Tag}
43
import graphql.UserGraphQLSchema.UserType
54
import io.circe.Json
65
import io.circe.generic.semiauto._
76
import model._
8-
import sangria.federation.v2.Directives.Key
7+
import sangria.federation.v2.Directives._
98
import sangria.federation.v2.{Decoder, EntityResolver}
109
import sangria.schema._
1110

@@ -17,16 +16,14 @@ object ProductGraphQLSchema {
1716
)
1817
)
1918

20-
private val ProductDimensionType: ObjectType[Unit, ProductDimension] = Shareable(
21-
ObjectType(
22-
"ProductDimension",
23-
fields = fields[Unit, ProductDimension](
24-
Field("size", OptionType(StringType), resolve = _.value.size),
25-
Field("weight", OptionType(FloatType), resolve = _.value.weight),
26-
Inaccessible(Field("unit", OptionType(StringType), resolve = _.value.unit))
27-
)
19+
private val ProductDimensionType: ObjectType[Unit, ProductDimension] = ObjectType(
20+
"ProductDimension",
21+
fields = fields[Unit, ProductDimension](
22+
Field("size", OptionType(StringType), resolve = _.value.size),
23+
Field("weight", OptionType(FloatType), resolve = _.value.weight),
24+
Field("unit", OptionType(StringType), resolve = _.value.unit, astDirectives = Vector(Inaccessible))
2825
)
29-
)
26+
).withDirective(Shareable)
3027

3128
private val CaseStudyType: ObjectType[Unit, CaseStudy] = ObjectType(
3229
"CaseStudy",
@@ -42,7 +39,7 @@ object ProductGraphQLSchema {
4239
Field("study", CaseStudyType, resolve = _.value.study),
4340
Field("outcome", OptionType(StringType), resolve = _.value.outcome)
4441
)
45-
).copy(astDirectives = Vector(Key("study { caseNumber }")))
42+
).withDirective(Key("study { caseNumber }"))
4643

4744
private val ProductType: ObjectType[Unit, Product] = ObjectType(
4845
"Product",
@@ -52,16 +49,19 @@ object ProductGraphQLSchema {
5249
Field("package", OptionType(StringType), resolve = _.value.`package`),
5350
Field("variation", OptionType(ProductVariationType), resolve = _.value.variation),
5451
Field("dimensions", OptionType(ProductDimensionType), resolve = _.value.dimensions),
55-
Provides("totalProductsCreated")(Field("createdBy", OptionType(UserType), resolve = _.value.createdBy)),
56-
Tag("internal")(Field("notes", OptionType(StringType), resolve = _.value.notes)),
52+
Field(
53+
"createdBy",
54+
OptionType(UserType),
55+
resolve = _.value.createdBy,
56+
astDirectives = Vector(Provides("totalProductsCreated"))
57+
),
58+
Field("notes", OptionType(StringType), resolve = _.value.notes, astDirectives = Vector(Tag("internal"))),
5759
Field("research", ListType(ProductResearchType), resolve = _.value.research)
5860
)
59-
).copy(astDirectives =
60-
Vector(
61-
Key("id"),
62-
Key("sku package"),
63-
Key("sku variation { id }")
64-
)
61+
).withDirectives(
62+
Key("id"),
63+
Key("sku package"),
64+
Key("sku variation { id }")
6565
)
6666

6767
private val DeprecatedProductType: ObjectType[Unit, DeprecatedProduct] = ObjectType(
@@ -72,11 +72,7 @@ object ProductGraphQLSchema {
7272
Field("reason", OptionType(StringType), resolve = _.value.reason),
7373
Field("createdBy", OptionType(UserType), resolve = _.value.createdBy)
7474
)
75-
).copy(astDirectives =
76-
Vector(
77-
Key("sku package")
78-
)
79-
)
75+
).withDirective(Key("sku package"))
8076

8177
val IdArg: Argument[String] = Argument("id", IDType)
8278
val SkuArg: Argument[String] = Argument("sku", StringType)

implementations/sangria/src/main/scala/graphql/UserGraphQLSchema.scala

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
package graphql
22

3-
import graphql.Directives.{External, Override, Requires}
43
import io.circe.Json
54
import model.{ID, User}
5+
import sangria.federation.v2.Directives._
66
import sangria.federation.v2.{Decoder, EntityResolver}
7-
import sangria.federation.v2.Directives.Key
87
import sangria.schema._
9-
import service.UserService
108

119
object UserGraphQLSchema {
1210
// should be "extend", but according to the spec, an extend type can only exist if there is one type:
1311
// http://spec.graphql.org/draft/#sec-Object-Extensions.Type-Validation
1412
val UserType: ObjectType[Unit, User] = ObjectType(
1513
"User",
1614
fields = fields[Unit, User](
17-
External(Field("email", IDType, resolve = _.value.email.value)),
18-
Override("users")(Field("name", OptionType(StringType), resolve = _.value.name)),
19-
External(Field("yearsOfEmployment", IntType, resolve = _.value.yearsOfEmployment)),
20-
External(Field("totalProductsCreated", OptionType(IntType), resolve = _.value.totalProductsCreated)),
21-
Requires("totalProductsCreated yearsOfEmployment")(
22-
Field("averageProductsCreatedPerYear", OptionType(IntType), resolve = _.value.averageProductsCreatedPerYear)
15+
Field("email", IDType, resolve = _.value.email.value, astDirectives = Vector(External)),
16+
Field("name", OptionType(StringType), resolve = _.value.name, astDirectives = Vector(Override("users"))),
17+
Field("yearsOfEmployment", IntType, resolve = _.value.yearsOfEmployment, astDirectives = Vector(External)),
18+
Field(
19+
"totalProductsCreated",
20+
OptionType(IntType),
21+
resolve = _.value.totalProductsCreated,
22+
astDirectives = Vector(External)
23+
),
24+
Field(
25+
"averageProductsCreatedPerYear",
26+
OptionType(IntType),
27+
resolve = _.value.averageProductsCreatedPerYear,
28+
astDirectives = Vector(Requires("totalProductsCreated yearsOfEmployment"))
2329
)
2430
)
25-
).copy(astDirectives = Vector(Key("email")))
31+
).withDirective(Key("email"))
2632

2733
implicit val decoder: Decoder[Json, ID] = ID.decoder.decodeJson
2834

0 commit comments

Comments
 (0)