arianegraphql / ariane-server

ArianeGraphQL server library
MIT License
7 stars 0 forks source link

Custom input types #11

Closed rb090 closed 6 months ago

rb090 commented 11 months ago

Hi ๐Ÿ‘‹,

1st of all thanks a lot for this wonderful Kotlin GQL server which is compatible with KTor. I really like it.

I have few small question please. Please be patient with me I am really a beginner when it comes in writing GQL servers. So I really don't have that much experience.

When I have custom input types within my schema, used on the GQL operations like fe. within a Mutation, how to correctly retrieve them in the code?

Fe. I have this schema:

input UserObjectInput {
    userId: String!
    userName: String
    userBirthday: String
}

type ResultObject {
    attributeA: String!
    attributeB: String!
    attributeC: String
    productType: ProductType
}

enum ProductType {
    PRODUCT_A,
    PRODUCT_B,
    UNKNOWN
}

type Mutation {
    mutationWithUser(user: UserObjectInput!): ResultObject!
}

type Query {
    helloWorld: String
}

My Application class of my Ktor Server looks like this:

// Input object for GQL input object "UserObjectInput" from schema.graphql
data class MyUserInput(id: String, name: String?, birthday: String?)

// How to map ProductType schema enum to this Kotlin enum?
enum class ProductType { A_PRODUCT, B_PRODUCT, UNKNOWN }

data class MyResult(myAttr1: String, myAttr2: String, myAttr3: String?, type: ProductType)

fun main() {

    arianeServer {
        // Load schema.graphql file from resources folder
        schema = loadSchema("schema.graphql")
        //Indicate which HTTP port should be used (80 by default)
        port = 3000

        serverListener = object : ServerListener {
            override fun onStart(host: String, port: Int, path: String) {
                log.info("Server ready ๐Ÿš€. Listening at http://localhost:$port$path")
            }
        }

        resolvers {
            Mutation {
                resolve("mutationWithUser") {
                    // The retrieved object by arguments is a LinkedHashMap?
                    // Do I manually need to create here `MyUserInput` oject from this `LinkedHashMap`
                    val user: LinkedHashMap<String, Any> = arguments["user"]

                    // Here the outcome of function `doSth()` would be `MyResult`
                    // How to map this to the GQL schema object `ResultObject`?
                    val result: MyResult = doSth()
                    result
                }
            }

        }
    }.launch()
}

Can you please tell me how the mapping "schema GQL objects" <-> Kotlin data classes needs to work with ariane-server? The mapping is my only issue here.

mbiamont commented 11 months ago

Hey,

Thanks for your comment, unfortunately, it's not possible yet. The project is still in early stage.

But I'm actively working on it. I'll keep you posted once it's possible.

rb090 commented 11 months ago

Hi @mbiamont,

wow cool, thank you so much ๐Ÿ™Œ. I really like your code. It is so nice and clean. I would be really more than happy to support if I can. Please just let me know. At least testing is sth I can do quite good. Integrate it, try it out and all that stuff.

Tbh - before starting with Ariane, I did also a research about existing libraries. There are a couple of them, listed on the โ€œofficialโ€ community page of graphql. But none of them really convinced me. They are really heavy and I have a really small use case. So then I found your library and I was really amazed.

mbiamont commented 10 months ago

Hello @rb090

I just published a new version that should handle argument typing (v0.3.0). Also, I published a Gradle plugin.

The plugin will generate the types according to your graphQL schema, and the resolver functions. For instance, with this plugin, instead of writing

resolvers {
   Mutation {
      resolve<UserObjectInput>("mutationWithUser") {
         println("User ID = ${it.userId}")
      }
   }
}

You can write

resolvers {
   Mutation {
      mutationWithUser { (user) ->
         println("User ID = ${user.userId}")
      }
   }
}

More info here: https://arianegraphql.com/docs/codegen

Feel free to test it out and give me your feedback ๐Ÿ™