GraphQL request string builder written in Kotlin

Overview

Kraph Build Status Download codecov

In short, this is a GraphQL request JSON body builder for Kotlin. It will generate the JSON string for request body that work with GraphQL Server. For example, we have this GraphQL query to list all notes:

query {
    notes {
        id
        createdDate
        content
        author {
            name
            avatarUrl(size: 100)
        }
    }
}

Which is written in Kotlin using Kraph like this:

Kraph {
    query {
        fieldObject("notes") {
            field("id")
            field("createdDate")
            field("content")
            fieldObject("author") {
                field("name")
                field("avatarUrl", mapOf("size" to 100))
            }
        }
    }
}

As you can see, we can achieve our goal with just a few tweaks from the original query.

NOTE: Kraph is still in an early stage. The usage may change in further development.

Features

  • DSL builder style. Make it easier to read and use.
  • Support Cursor Connection and Input Object Mutation in Relay.

Set up

Adding Kraph to build.gradle

repositories {
    jcenter()
}

dependencies {
    compile "me.lazmaid.kraph:kraph:x.y.z"
}

Guide

If you are not familiar with GraphQL syntax, it is recommended to read the GraphQL introduction for an overview of how Graphql works. Usually, you should be able to use queries from other tools (e.g. GraphiQL) with a few tweaks. First, let's see what Kraph provides for you.

Simple GraphQL

  • query and mutation represents the Query and Mutation operations of GraphQL. The name of the query or mutaton can be passed as a string.

    GraphQL:

    query GetUsers {
      ...
    }

    Kraph:

    Kraph {
        query("GetUsers") {
            ...
        }
    }

    GraphQL:

    mutation UpdateUserProfile {
      ...
    }

    Kraph:

    Kraph {
        mutation("UpdateUserProfile") {
            ...
        }
    }
  • field and fieldObject represent accessors for fields. Though there are technically no differences, fieldObject may be chosen for clarity to indicate that a field must contain another set of nested fields as an argument. Both of them take a Map<String, Any> that maps Kotlin data types to the GraphQL data types for input objects. You can also specify an alias using alias to change the name of the returned field.

    query {
      users {
        nick: name
        email
        avatarUrl(size: 100)
      }
    }
    Kraph {
        query {
            fieldObject("users") {
                field("name", alias = "nick")
                field("email")
                field("avatarUrl", args = mapOf("size" to 100))
            }
        }
    }
  • fragment provides a mechanism for creating GraphQL Fragments. To use a fragment in a query requires two steps. The first is to define the fragment, letting Kraph know how to handle it later:

    fragment UserFragment on User {
      name
      email
      avatarUrl(size: 100)
    }
    Kraph.defineFragment("UserFragment") {
        field("name")
        field("email")
        field("avatarUrl", mapOf("size" to 100))
    }

    Then, when you are creating your query, you can simply use the fragment and its fields will be expanded:

    query {
      users {
        ...UserFragment
      }
    }
  • fragment provides a mechanism for creating GraphQL Fragments. To use a fragment in a query requires two steps. The first is to define the fragment, letting Kraph know how to handle it later:

    fragment UserFragment on User {
      name
      email
      avatarUrl(size: 100)
    }
    Kraph.defineFragment("UserFragment") {
        field("name")
        field("email")
        field("avatarUrl", mapOf("size" to 100))
    }

    Then, when you are creating your query, you can simply use the fragment and its fields will be expanded:

    query {
      users {
        ...UserFragment
      }
    }
    Kraph {
        query("GetUsers") {
            fieldObject("users") {
                fragment("UserFragment")
            }
        }
    }

Relay

  • func represents a Field inside a Mutation block that follows the Relay Input Object Mutations specification.
    mutation {
      userLogin(input: {email: "[email protected]", password: "abcd1234"}) {
        accessToken
        user {
          id
          email
        }
      }
    }
    Kraph {
        mutation {
            func("userLogin", input = mapOf("email" to "[email protected]", "password" to "abcd1234")) {
                field("accessToken")
                fieldObject("user") {
                    field("id")
                    field("email")
                }
            }
        }
    }
  • cursorConnection represents a Field that follows the Relay Cursor Connections specification
    query {
       users(first: 10, after: "user::1234") {
        edges {
          node {
            id
            name
          }
        }
      }
    }
    Kraph {
        cursorConnection("users", first = 10, after = "user::1234") {   
            edges {
                node {
                    field("id")
                    field("name")
                }
            }
        }
    }

Request/Query String

  • toRequestString() will generate a JSON body to send in POST request.
  • toGraphQueryString() will give you the formatted GraphQL string. This is very useful for debugging.
    val query = Kraph {
        query {
            fieldObject("users") {
                field("name")
                field("email")
                field("avatarUrl", args = mapOf("size" to 100))
            }
        }
    }    
    
    println(query.toRequestString())
    /*
     * Result:
     * {"query": "query {\nnotes {\nid\ncreatedDate\ncontent\nauthor {\nname\navatarUrl(size: 100)\n}\n}\n}", "variables": null, "operationName": null}
     */
    println(query.toGraphQueryString())
    /*
     * Result:
     * query {
     *   notes {
     *     id
     *     createdDate
     *     content
     *     author {
     *       name
     *       avatarUrl(size: 100)
     *     }
     *   }
     * }
     */
  • requestQueryString(), requestVariableString() and requestOperationName() provide more fine grained access to the components of the full request string, which are sometimes necessary depending on your HTTP request builder and GraphQL server setup. They provide the values for the query, variables, and operationName parameters, respectively, and so are good for creating GET requests. Please note that requestVariableString() will always return null until variable support is implemented.

Contributing to Kraph

We use Github issues for tracking bugs and requests. Any feedback and/or PRs is welcome.

Comments
  • Crash because of Unsupported Type

    Crash because of Unsupported Type

    My code worked fine on version 0.5.0, but always crash because of Unsupported Type after upgrade to 0.5.1 or 0.6.0

    Here is the crash log:

                                                                                      Process: cn.fashicon.fashicon.development, PID: 17760
                                                                                      java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.fashicon.fashicon.development/cn.fashicon.fashicon.home.TabActivity}: java.lang.RuntimeException: 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                                                                                       Caused by: java.lang.RuntimeException: 
    at me.lazmaid.kraph.lang.GraphQLNode.convertToDataEntry(GraphQLNode.kt:35)
    at me.lazmaid.kraph.lang.GraphQLNode.access$convertToDataEntry(GraphQLNode.kt:3)
    at me.lazmaid.kraph.lang.GraphQLNode$print$1.invoke(GraphQLNode.kt:13)
    at me.lazmaid.kraph.lang.GraphQLNode$print$1.invoke(GraphQLNode.kt:3)
    at kotlin.text.StringsKt__StringBuilderKt.appendElement(StringBuilder.kt:59)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinTo(_Collections.kt:2023)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinToString(_Collections.kt:2038)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinToString$default(_Collections.kt:2037)
    at me.lazmaid.kraph.lang.GraphQLNode.print(GraphQLNode.kt:12)
    at me.lazmaid.kraph.lang.Argument.print(Argument.kt:12)
    at me.lazmaid.kraph.lang.Field.print(Field.kt:17)
    at me.lazmaid.kraph.lang.SelectionSet$print$fieldStr$1.invoke(SelectionSet.kt:15)
    at me.lazmaid.kraph.lang.SelectionSet$print$fieldStr$1.invoke(SelectionSet.kt:7)
    at kotlin.text.StringsKt__StringBuilderKt.appendElement(StringBuilder.kt:59)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinTo(_Collections.kt:2023)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinToString(_Collections.kt:2038)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinToString$default(_Collections.kt:2037)
    at me.lazmaid.kraph.lang.SelectionSet.print(SelectionSet.kt:15)
    at me.lazmaid.kraph.lang.Field.print(Field.kt:16)
    at me.lazmaid.kraph.lang.SelectionSet$print$fieldStr$1.invoke(SelectionSet.kt:15)
    at me.lazmaid.kraph.lang.SelectionSet$print$fieldStr$1.invoke(SelectionSet.kt:7)
    at kotlin.text.StringsKt__StringBuilderKt.appendElement(StringBuilder.kt:59)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinTo(_Collections.kt:2023)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinToString(_Collections.kt:2038)
    at kotlin.collections.CollectionsKt___CollectionsKt.joinToString$default(_Collections.kt:2037)
    at me.lazmaid.kraph.lang.SelectionSet.print(SelectionSet.kt:15)
    at me.lazmaid.kraph.lang.Operation.print(Operation.kt:19)
    at me.lazmaid.kraph.lang.Document.print(Document.kt:15)
    at me.lazmaid.kraph.Kraph.toRequestString(Kraph.kt:42)
    at cn.fashicon.fashicon.data.DataProvider.getProfileInfo(DataProvider.java:237)
    at cn.fashicon.fashicon.profile.domain.usecase.GetProfileInfo.buildUseCase(GetProfileInfo.java:25)
    at cn.fashicon.fashicon.profile.domain.usecase.GetProfileInfo.buildUseCase(GetProfileInfo.java:16)
    at cn.fashicon.fashicon.NetworkUseCase.execute(NetworkUseCase.java:51)
    at cn.fashicon.fashicon.NetworkUseCase.execute(NetworkUseCase.java:47)
    at cn.fashicon.fashicon.home.TabPresenter.getMe(TabPresenter.java:190)
    at cn.fashicon.fashicon.home.TabActivity.onCreate(TabActivity.java:185)
    at android.app.Activity.performCreate(Activity.java:6975)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
    at cn.jiguang.a.a.d.a.a.d.callActivityOnCreate(Unknown Source:24)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
    at android.os.Handler.dispatchMessage(Handler.java:105) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6541) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) ```
    
    And this is the query:
    
    ```       fun getProfileInfo(userId: String, myUserId: String, first: Int, after: String): Kraph {
                return Kraph {
                    query {
                        fieldObject("user", args = mapOf("userId" to userId)) {
                            field("userId")
                            field("profileMediaUrl")
                            field("followingCount")
                            field("followerCount")
                            field("lookCount")
                            field("username")
                            field("userSig")
                            field("userType")
                            field("isLoggedInTencent")
                            field("followed: isFollowedBy", args = mapOf("followerId" to myUserId))
                            fieldObject("badgeInfo") {
                                fieldObject("lookLevel") {
                                    field("levelKey")
                                    field("nextLevelKey")
                                    field("from")
                                    field("to")
                                }
                                fieldObject("adviceLevel") {
                                    field("levelKey")
                                    field("nextLevelKey")
                                    field("from")
                                    field("to")
                                }
                            }
                            fieldObject("lookScoreInfo: scoreInfo", args = mapOf("by" to LeaderBoardBy.LOOKS_RATINGS, "period" to LeaderBoardPeriod.ALL_TIME)) {
                                field("score")
                            }
                            fieldObject("adviceScoreInfo: scoreInfo", args = mapOf("by" to LeaderBoardBy.ADVICE_RATINGS, "period" to LeaderBoardPeriod.ALL_TIME)) {
                                field("score")
                            }
                        }
                        fieldObject("looksPaginated", args = mapOf("userId" to userId, "first" to first, "after" to after)) {
                            fieldObject("edges") {
                                fieldObject("node") {
                                    field("lookId")
                                    field("userId")
                                    field("title")
                                    field("totalRating")
                                    fieldObject("rating", args = mapOf("raterId" to myUserId)) {
                                        field("raterId")
                                        field("lookId")
                                        field("stars")
                                    }
                                    field("adviceCount")
                                    fieldObject("lookMedias") {
                                        field("title")
                                        field("url")
                                        fieldObject("tags"){
                                            fieldObject("brand"){
                                                field("brandId")
                                                field("name")
                                            }
                                            fieldObject("category"){
                                                field("categoryId")
                                                field("name")
                                            }
                                            fieldObject("location"){
                                                field("x")
                                                field("y")
                                            }
                                        }
                                    }
                                }
                            }
                            fieldObject("pageInfo") {
                                field("endCursor")
                                field("hasNextPage")
                            }
                        }
                    }
                }
            }
    

    WHich was wrong in my situation?

    opened by IHNEL 8
  • List with quotes

    List with quotes

    Hi,

    I'm trying to send a list of items into a mutation. But, I'm receiving a

    Cannot parse the unexpected character \".\".\n\
    

    The rendered query doesn't contain quotes (I think that's the problem). Do you have any solutions for that?

    Query:

    fun updateSomething(mylist: ArrayList<String>): Kraph {
        return Kraph {
            mutation {
                func("updateSomething", args = mapOf("mylist" to mylist)) {
                    field("mylist")
                }
            }
        }
    }
    

    This will render:

    {"query": "mutation { \nupdateSomething(input: { mylist: [item1, item2] }) {\nmylist\n}\n}", "variables": null, "operationName": null}
    
    bug 
    opened by eduardostuart 7
  • How to pass listOf object to mutation

    How to pass listOf object to mutation

    Hello, Prior 0.4.1 I was able to pass a list of object using: val lookMediaInputs = listOf("{title: \"${media.title}\", type: \"${media.type}\", fileFieldname: \"${media.fileFieldname}\"}") and mapOf("lookMediaInputs" to lookMediaInputs) I cannot do that anymore, so how can I pass a list of object to mapOf for a mutation? Thanks!

    opened by blacroix 5
  • How to use

    How to use "variables" ?

    Hi,

    How can I set "variables" in a query?

    For example, if I have the query/mutation:

    val args = mutableMapOf<String, Any>()
    args.put("language", "en-us")
    
    return Kraph {
        mutation("settings") {
            func("settings", args) {
                field("language")
            }
        }
    }
    

    This will result in:

    {
       "query":"mutation settings {\nlanguage(language: \"en-us\")\n}",
       "variables":null,
       "operationName":"settings"
    }
    

    But, how do I put "variables"? Like this:

    {
       "query":"mutation settings($settings: SettingsInput!) {\n  settings(input: $settings) {\n    language\n     }\n}\n",
       "variables":{
          "settings":{
             "language":"en-us"
          }
       },
       "operationName":"settings"
    }
    
    opened by eduardostuart 5
  • Support for variables

    Support for variables

    Is there support for query variables?

    I've found that there's additional DSL for variables in this fork: https://github.com/makarenkoanton/kraph

    But I don't see it in the main project.

    opened by AlexeySoshin 4
  • Added partial request printing functions

    Added partial request printing functions

    Was having trouble sending GET requests with this properly as the only "query only" string was pretty printed, so I added some functions to break up that one for writing POST requests. Changed the output format a bit too, so it would be a bit more readable/standard looking. Seems to be working from my app, and fixed up the tests that had to change for this.

    Not sure why there are so many commits listed. Seems like a lot of the ones from the last PR.

    opened by foxfriends 4
  • Fragments

    Fragments

    Is possible to build "fragments" with Kraph?

    Example:

    Fragment:

    fragment something on SomethingXX {
       id
       name
    }
    

    Full query:

    query queryname($input: QueryInput!) {
      queryname(input: $input) {
        message
        ... on SomeResult {
          somethinghere {
            ...something
          }
        }
      }
    }
    
    opened by eduardostuart 4
  • When will the next release?

    When will the next release?

    I want to use the feature(https://github.com/VerachadW/kraph/pull/23), but it not found in 0.6.0. It is my mistake or it is not included in version 0.6.0?

    opened by jershell 3
  • add alias support for queries and mutations

    add alias support for queries and mutations

    Hey there,

    I added the support to aliasing queries and mutations like here: http://graphql.org/learn/queries/#aliases

    Kraph {
      query("getAllNotes") {
        fieldObject("notes", alias = "aliasedNotes") {
          field("id", alias = "aliasedId")
        }
     }
    

    Cheers, Andreas

    opened by athurn 3
  • Bugfix when use tr locale

    Bugfix when use tr locale

    This bugfix . It cause then user select turkish locale on android device. This example desmonstrate troube

    package com.github.test.error
    
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.util.Log
    import java.util.*
    
    internal enum class OperationType {
        QUERY,
        MUTATION
    }
    
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val trLocaleFromOsSettings = Locale("tr")
            val enLocaleSoSettings = Locale.ENGLISH
            val sTypeFromEnumField = OperationType.MUTATION.name.toLowerCase(trLocaleFromOsSettings)
            val sTypeFromString = "MUTATION".toLowerCase(trLocaleFromOsSettings)
            val sTypeFromInit = "mutation"
            Log.d("TEST", "LOCALE -> ${trLocaleFromOsSettings.language}")
    
            Log.d("TEST", "sTypeFromEnumField -> $sTypeFromEnumField")
            Log.d("TEST", "sTypeFromString -> $sTypeFromString")
            Log.d("TEST", "sTypeFromString -> $sTypeFromString")
            Log.d("TEST", "sTyleFromInit -> $sTypeFromInit")
            Log.d("TEST", "sTyleFromInit == sTypeFromString -> ${sTypeFromInit == sTypeFromString}")
            Log.d("TEST", "sTyleFromInit == sTypeFromString -> ${sTypeFromInit == sTypeFromEnumField}")
        }
    }
    
    
    

    Output:

    06-17 17:00:31.166 27489-27489/? D/TEST: LOCALE -> tr
    06-17 17:00:31.166 27489-27489/? D/TEST: sTypeFromEnumField -> mutatıon
    06-17 17:00:31.166 27489-27489/? D/TEST: sTypeFromString -> mutatıon
    06-17 17:00:31.166 27489-27489/? D/TEST: sTypeFromString -> mutatıon
    06-17 17:00:31.166 27489-27489/? D/TEST: sTyleFromInit -> mutation
    06-17 17:00:31.166 27489-27489/? D/TEST: sTyleFromInit == sTypeFromString -> false
    06-17 17:00:31.166 27489-27489/? D/TEST: sTyleFromInit == sTypeFromString -> false
    

    i didnt use Locale.ENGLISH since i want to avoid java dependencies

    opened by jershell 2
  • Queries without mutation or query

    Queries without mutation or query

    I have to make a query which goes like this

    {
    something(type: App) {
    count
    }
    }
    

    how do I do that with Kraph? I dont seem to be able to do it, just use mutation/query

    opened by nihiluis 2
  • Field objects are allowed to be supplied without declaring blocks

    Field objects are allowed to be supplied without declaring blocks

    GraphQL endpoints do not necessarily need to specify fields as arguments when a mutation or query is received. Diverse implementations on the server-side will allow for returning non-standardized data formats, such as JSON, which breaks this library.

    Fixes: https://github.com/VerachadW/kraph/issues/31

    opened by rudy-on-rails 1
  • Accidental breakage in 0.6.1

    Accidental breakage in 0.6.1

    Hello, just thought you should know that by adding the alias parameter in the fieldObject() function, but not placing it last, you broke at least some code in our projects. We fixed it by naming the arguments in the function calls, but it would have been better to not break them at all :)

    opened by tofagerl 0
  • Request without returning parameters

    Request without returning parameters

    Hello, guys, thanks for you work. Could you please help me to find out how to build following query with kraph:

    query {
        vendors(dc: 5820)
    }
    

    Here is part of my schema:

    type Query {
        vendors(dc: Int!): [Int]
    }
    

    I've already tried to execute this code:

    Kraph {
        query {
            func(name = "vendors", args = mapOf("dc" to 5820)) {}
        }
    }
    

    But it fails with exception: me.lazmaid.kraph.NoFieldsInSelectionSetException: No field elements inside "vendors" block

    Thanks!

    opened by Rinat-Suleimanov 1
Releases(v.0.6.1)
Owner
Verachad Wongsawangtham
Mobile developer, mostly on Kotlin
Verachad Wongsawangtham
GraphQL Jetpack - A collection of packages for easily writing Java GraphQL server implementations

GraphQL Jetpack A collection of packages for easily writing Java GraphQL server

Ryan Yang 18 Dec 2, 2022
Victor Hugo 1 Feb 2, 2022
Kotlin Multiplatform String markup library

Thistle Kotlin multiplatform String markup library, inspired by SRML. Thistle is a common parser which produces an AST that can be rendered to a varie

Copper Leaf 52 Dec 30, 2022
Nice String in Kotlin

Nice String We'll say a string is nice if at least two of the following conditio

Bunyod Rafikov 0 Dec 28, 2021
A sample skeleton backend app built using Spring Boot kotlin, Expedia Kotlin Graphql, Reactive Web that can be deployed to Google App Engine Flexible environmennt

spring-kotlin-gql-gae This is a sample skeleton of a backend app that was built using: Spring Boot(Kotlin) Reactive Web Sprinng Data R2DBC with MYSQL

Dario Mungoi 7 Sep 17, 2022
FizzBuzzKotlin - A function fizzBuzz to generate a list of string based on the input number

FizzBuzzKotlin write a function fizzBuzz to generate a list of string based on t

gson 0 Feb 12, 2022
Kotlin backend based on the Clean Architecture principles. Ktor, JWT, Exposed, Flyway, KGraphQL/GraphQL generated endpoints, Gradle.

Kotlin Clean Architecture Backend Kotlin backend based on the Clean Architecture principles. The application is separated into three modules: Domain,

null 255 Jan 3, 2023
🗼 yukata (浴衣) is a modernized and fast GraphQL implementation made in Kotlin

?? yukata 浴衣 - Modernized and fast implementation of GraphQL made in Kotlin yukata is never meant to be captialised, so it'll just be yukata if you me

Noel 5 Nov 4, 2022
An application that simulate the Swedish Transport Agency, implemented with Spring Boot, Kotlin and GraphQL

graphql-kotlin-spring-server An application that simulate the Swedish Transport Agency, implemented with Spring Boot, Kotlin and GraphQL Running the s

null 0 Oct 31, 2021
A simple reference example Kotlin GraphQL service

A simple reference example Kotlin GraphQL service, written for colleagues coming over from Python & FastAPI/Flask + Ariadne/Graphene.

Dan Pozmanter 5 Mar 20, 2022
GraphQL for Java with Spring Boot made easy.

GraphQL for Java with Spring Boot made easy.

Netflix, Inc. 2.5k Jan 9, 2023
This repository demonstrates Spring GraphQL + RSocket + WebFlux + R2DBC + H2

Reactive GraphQL with Spring This repository demonstrates Spring GraphQL + RSocket + WebFlux + R2DBC + H2 O__ +-----------+

Maksim Kostromin 1 Nov 27, 2021
PeopleInSpace GraphQL Server

PeopleInSpace GraphQL Server GraphQL backend allowing querying list of people in

John O'Reilly 5 Oct 4, 2022
Template to accelerate the creation of new apps using Spring Boot 3, MongoDB & GraphQL.

Template to accelerate the creation of new apps using Spring Boot 3, MongoDB & GraphQL.

André Ramon 1 Feb 13, 2022
Koltin Multplatform Project that interacts with a GraphQL server to display golf scores, player and weather information.

GolfScoresKMM Koltin Multplatform Project that interacts with a GraphQL server to display golf scores, player and weather information. The app is setu

Mohit 15 Oct 21, 2022
Mock up social media android application created to interact with a backend Java server using GraphQL.

The Community Board Project Authorship: author: dnglokpor date: may 2022 Project Summary: The Community Board Project consists of a Java Spring Boot b

Delwys Glokpor 1 May 17, 2022
Android app to fetch closed pull request of any public repo

Pullr Android app to fetch closed pull request of any public repo ?? Features Co

Sonu Sourav 2 Sep 17, 2022
This library handles conversion between Request Params and JPA Specification.

Spring Jpa Magic Filter This library handles conversion between spring rest Request Params and JPA Specification. It can be considered a simpler alter

Verissimo Joao Ribeiro 4 Jan 12, 2022
A demo project which demonstrates the work of javax.servlet.Filter capable of escaping / modifying / removing a part of JSON request based on specified criteria.

Replace Filter Demo A demo project which demonstrates the work of javax.servlet.Filter capable of escaping / modifying / removing a part of JSON reque

Vlad Krava 1 Jan 17, 2022