tgirard12 / graphql-kotlin-dsl

Kotlin DSL to generate GraphQl Schema
Apache License 2.0
7 stars 2 forks source link
dsl graphql graphql-java graphql-tools kotlin

= graphql-kotlin-dsl

:sectanchors:

image::https://api.bintray.com/packages/tgirard12/kotlin/graphql-kotlin-dsl/images/download.svg[link="https://bintray.com/tgirard12/kotlin/graphql-kotlin-dsl/_latestVersion"]

Kotlin DSL to generate GraphQL Instance and Schema IDL for https://github.com/graphql-java/graphql-java

== Download

[source,groovy]

compile 'com.tgirard12:graphql-kotlin-dsl:VERSION'

== Sample

[source,kotlin]

data class User( val name: String, val email: String, val deleteField: Int )

enum class Right { read, write, execute }

schemaDsl { // Scalar scalar { GqlJavaScalars.double } scalar { GqlJavaScalars.uuid }

// Types and Enums
type<User>(typeDescription = "An User") {
    desc("email", "User Email")

    addField<String>(name = "otherName") {
        asyncDataFetcher<String>("otherName") {
            "MyOtherName"
        }
    }

    addField<Right> {
        description = "User Right"
        nullable = true
        asyncDataFetcher<Right>("right") {
            Right.execute
        }
    }

    dropField("deleteField")
}
enum<Right>(enumDescription = "An enum") { }

// Queries
query<User>(queryDescription = "User By Id") {
    arg<UUID> { name = "id" }

    asyncDataFetcher { env ->
        Stubs.users.firstOrNull { it.id == env.arguments["id"] }
    }
}
query<Unit> {
    name = "users"
    description = "All Users"
    returnType = "[User]"

    staticDataFetcher {
        Stubs.users
    }
}

// Mutations
mutation<User>(mutationDescription = "Update a user") {
    name = "updateUser"

    arg<Int> {
        name = "count"
        nullable = true
    }
    arg<String> { name = "name" }

    asyncDataFetcher { env ->
        User(UUID.randomUUID(), env.arguments["name"] as String, "email@gql.io", 5)
    }
}

}.graphQL { queryExecutionStrategy(AsyncExecutionStrategy())

}.execute(""" query user { user(id: "b6214ea0-fc5a-493c-91ea-939e17b2e95f") { id email name otherName right } }""")

== How that work

:sectnums:

1. Generate this GraphQl String schema :

[source]

schema { query: QueryType mutation: MutationType }

type QueryType {

User By Id

user(id: UUID!): User!
# All Users
users: [User]!

}

type MutationType {

Update a user

updateUser(count: Int, name: String!): User!

}

scalar Double scalar UUID

An enum

enum Right { read write execute }

An User

type User {

User Email

email: String!
id: UUID!
name: String!

otherName: String!
# User Right
right: Right

}

2. Use the DataFetcher from the DSL to generate RuntimeWiring :

3. Configure GraphQl.Builder()

:sectnums!:

[[Extension]] == graphql-java Extension functions and DSL

link:src/test/kotlin/com/tgirard12/graphqlkotlindsl/execution/ExecutionTest.kt#L39[Show graphQL sample]

[[RuntimeWiring]] === GraphQL and RuntimeWiring DSL

[source,kotlin]

schemaDsl { ... }.graphQL({ // Define RuntimeWiring.Builder

scalarUUID() scalarDouble()

queryType { staticDataFetcher<List>("users") { users } asyncDataFetcher("user") { e -> e.arguments["id"]?.let { id -> users.firstOrNull { id == it.id } } } } mutationType { asyncDataFetcher("updateUser") { e -> User(id = UUID.fromString("773b29ba-6b2b-49fe-8cb1-36134689c458"), name = e.arguments["name"] as String? ?: "", email = e.arguments["email"] as String) } } type { asyncDataFetcher("user") { users[0] } // Custom fetcher for SimpleTypes.user } }, { GraphQL.Builder queryExecutionStrategy(AsyncExecutionStrategy()) })

[[GraphQLSchema]] === GraphQLSchema instance

[source,kotlin]

schemaDsl { ... }.graphQLSchema(myRuntimeWiring)

[[Scalar]] === Scalar DSL

[source,kotlin]

val scalar = scalarTypeDsl { serialize { // ... } parseValue { // ... } parseLiteral { // ... } }

link:src/main/kotlin/com/tgirard12/graphqlkotlindsl/graphqljava/GqlJavaScalars.kt#L12[Show scalars sample]

Custom scalars : GqlJavaScalars.uuid, GqlJavaScalars.double