Starting Schema
We will be making a group chat app (without the user authentication)
#
Write a SchemaLet's look at what the final schema look like:
Feel free to customize the schema to your liking
schema.graphql
type Message { id: ID! content: String! authorName: String! createdAt: String!}
type Query { messages(limit: Int! = 30): [Message!]! messageBy(authorName: String!): [Message!]!}
type Mutation { send(msg: String!, by: String!): Message!}
type Subscription { roomLobby: Message!}
#
Sangria Required TypesSangria Schema are written with a required context and root value type. So, let's create a basic context type that can be updated later on.
Stub context case class
Context.scala
case class Context( // Will be added later)
#
Sangria Object TypesI am assumming some sangria knowledge here. Let's create all the proper object types excluding the subscription.
#
Message Object TypeMessage.scala
import sangria.schema._import sangria.macros.derive._import /*path to file*/.Contextimport java.time.Instant
case class Message( id: String, content: String, authorName: String,) { val createdAt: String = Instant.now().toString}
object Message { val t = deriveObjectType[Context, Message]( AddFields( Field("createdAt", StringType, resolve = _.value.createdAt) ) )}
Equivalent ObjectType (from the GraphQL SDL)
#
Root / Top Level ObjectNow, we have all the ObjectType
that isn't a RootOperationType. We can start writing the top level objects primarily the Query
and Mutation
as the Subscription
require a bit more work which will be described on the next page.
Schema.scala
import sangria.schema._import scala.math.minimport java.util.UUIDimport /*path to file*/.Contextimport /*path to file*/.Message
object Schema { val limitArg = Argument("limit", IntType, defaultValue = 30) val authorNameArg = Argument("authorName", StringType)
val QueryType = ObjectType( "Query", fields[Context, Unit]( Field("messages", ListType(Message.t), arguments = limitArg :: Nil, // We will be updating this later on resolve = c => List[Message]().reverse.take(min(c.arg(limitArg), 100)) ), Field("messageBy", ListType(Message.t), arguments = authorNameArg :: Nil, // We will be updating this later on resolve = c => List[Message]().reverse.filter(_.authorName == c.arg(authorNameArg)) ) ) )
val (byArg, msgArg) = ( Argument("by", StringType), Argument("msg", StringType) )
val MutationType = ObjectType( "Mutation", fields[Context, Unit]( Field("send", ListType(Message.t), arguments = msgArg :: byArg :: Nil, // We will be updating this later on resolve = c => Message( id = UUID.randomUUID().toString, content = c.arg(msgArg), authorName = c.arg(byArg) ) ) ) )
val t = Schema(QueryType, Some(MutationType))}
Equivalent ObjectType (from the GraphQL SDL)
Although the resolvers are incomplete due to lack of data, We already put in place the appropriate logic so it will be an easy refactor.