Skip to content
This repository has been archived by the owner on Feb 14, 2020. It is now read-only.

chRyNaN/graphql-query-builder

Repository files navigation

graphql-query-builder

A Mutliplatform Kotlin Library to facilitate the creation of type-safe GraphQL Request Query DSLs.

Note: This is an older library experiment that is no longer being maintained. Please refer to the newer library: graphkl.

Library Objective

This library helps create GraphQL request strings to send to a server. It does this by providing DSL Builder Classes which wrap a StringBuilder and handle building a dynamic GraphQL request string in proper format. These DSL Builder Classes can be extended from custom classes to create a simple DSL for request queries.

Library Usage

The following GraphQL Schema:

type Account {
  id: ID!
  email: String!
  token: String!
}

type User {
  id: ID!
  name: String
  friends(count: Int!, cursor: Cursor): [String!]
  account: Account!
}

type Query {
    viewer: User!
}

Could be written using this library like so:

typealias Cursor = String

class AccountBuilder : GraphQLQueryBuilder() {

  val id by gqlScalar("id")
  
  val email by gqlScalar("email")
  
  val token by gqlScalar("token")
}

class UserBuilder : GraphQLQueryBuilder() {

  val id by gqlScalar("id")
  
  val name by gqlScalar("name")
  
  fun friends(count: Int, cursor: Cursor? = null) = gqlScalarWithParams(name = "friends", parameters = listOf(gqlParam(name = "count", value = count), gqlParam(name = "cursor", value = cursor)))
  
  fun account(builder: AccountBuilder.() -> Unit) = gqlObject(name = "account", objectBuilder = AccountBuilder(), objectFieldBuilder = builder)
}

class Root : RootGraphQLQueryBuilder() {

  fun viewer(builder: UserBuilder.() -> Unit) = gqlObject(name = "viewer", objectBuilder = UserBuilder(), objectFieldBuilder = builder)
}

Which allows you to create dynamic and type-safe queries in Kotlin like this:

val graphQLQuery = query(Root()){
  viewer {
    id
    name
    friends(count = 10)
    account {
      id
      email
      token
    }
  }
}

Queries

To perform a Query, you need a Root Query Builder Object. This Object is similar to the GraphQL Query type. Then, to obtain a GraphQLQuery object instance, use the query function.

GraphQL Definition:

type Query {
    viewer: User!
}

Kotlin Definition:

class Root : RootGraphQLQueryBuilder() {

    fun viewer(builder: UserBuilder.() -> Unit) = gqlObject(name = "viewer", objectBuilder = UserBuilder(), objectFieldBuilder = builder)
}

Kotlin Query:

val graphQLQuery = query(Root()) {
    viewer {
        id
        name
    }
}

You could even create a wrapper function around the query function to simplify it's syntax:

fun query(query: Root.() -> Unit) = query(builder = Root(), query = query)

...

val graphQLQuery = query {
    viewer {
        id
        name
    }
}

Mutations

To perform a Mutation, you need a Root Mutation Builder Object. This Object is similar to the GraphQL Mutation type. Then, to obtain a GraphQLQuery object instance, use the mutation function.

GraphQL Definition:

type Mutation {
    updateName(name: String!): User!
}

Kotlin Definition:

class Mutation : RootGraphQLMutationBuilder() {

    fun updateName(name: String, builder: UserBuilder.() -> Unit) = gqlObject(name = "updateName", parameters = listOf(gqlParam(name = "name", value = name)), objectBuilder = UserBuilder(), objectFieldBuilder = builder)
}

Kotlin Query:

val graphQLMutation = mutation(Mutation()) {
    updateName(name = "New Name") {
        id
        name
    }
}

You could even create a wrapper function around the mutation function to simplify it's syntax:

fun mutation(query: Mutation.() -> Unit) = mutation(builder = Mutation(), query = query)

...

val graphQLMutation = mutation {
    updateName(name = "New Name") {
        id
        name
    }
}

Subscriptions

To perform a Subscription, you need a Root Subscription Builder Object. This Object is similar to the GraphQL Subscription type. Then, to obtain a GraphQLQuery object instance, use the subscription function.

GraphQL Definition:

type Subscription {
    userChanges(id: String!): User!
}

Kotlin Definition:

class Subscription : RootGraphQLSubscriptionBuilder() {

    fun userChanges(id: String, builder: UserBuilder.() -> Unit) = gqlObject(name = "userChanges", parameters = listOf(gqlParam(name = "id", value = id)), objectBuilder = UserBuilder(), objectFieldBuilder = builder)
}

Kotlin Query:

val graphQLSubscription = subscription(Subscription()) {
    userChanges(id = "Some ID") {
        id
        name
    }
}

You could even create a wrapper function around the subscription function to simplify it's syntax:

fun subscription(query: Subscription.() -> Unit) = subscription(builder = Subscription(), query = query)

...

val graphQLSubscription = subsciption {
    userChanges(id = "Some ID") {
        id
        name
    }
}

Fragments

Basic GraphQL Fragments are supported by using the fragment() function:

val accountFragment = fragment<AccountBuilder>() on {
    email
    token
}

...

val graphQLQuery = query(Root()) {
    viewer {
        id
        name
        account {
            this..accountFragment
        }
    }
}

About

A Mutliplatform Kotlin Library to facilitate the creation of type-safe GraphQL Query Request DSLs

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages