GithubHelp home page GithubHelp logo

anitrend / retrofit-graphql Goto Github PK

View Code? Open in Web Editor NEW
109.0 7.0 19.0 5.6 MB

Retrofit converter which uses annotations to inject .graphql query or mutation files into a request body, along with any variables.

Home Page: https://anitrend.github.io/retrofit-graphql/

License: Apache License 2.0

Kotlin 99.92% Shell 0.08%
retrofit2 graphql retrofit-converter graphql-query graphql-variables persisted-queries graphql-files android

retrofit-graphql's People

Contributors

actions-user avatar cilenco avatar dependabot-preview[bot] avatar dependabot[bot] avatar eschlenz avatar github-actions[bot] avatar krillsson avatar renovate[bot] avatar rrva avatar wax911 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

retrofit-graphql's Issues

Allow subclasses of QueryContainerBuilder for requests

When defining the functions for our Graphql requests we have to put a QueryContainerBuilder as parameter which is a final class. If the related Graphql functions takes parameters as input we have to remember to pass these into the builder like this:

QueryContainerBuilder().putVariables(
    mapOf("arg1" to arg1, "arg2" to arg2)
)

It would be nice to let the type system take care of this. For this we have to pass a subclasses of QueryContainerBuilder into the functions where the constructor of that class takes care of the required arguments. Then we can define our functions like this:

class MyRequestArgs(arg1: Int, arg2: String): QueryContainerBuilder() { // Fails because QueryContainerBuilder is final
    init {
        putVariables(mapOf("arg1" to arg1, "arg2" to arg2))
    }
}

@POST("graphql") @GraphQuery("ItemRequest")
fun getItems(@Body builder: MyRequestArgs): ItemResponse

So in summary it would be great if QueryContainerBuilder could be an open class. However, I'm not entirely sure if this effects serialization and deserialization of request and response objects in any way.

Migrate to version cataloges for buildSrc

Issue Guidelines

Before opening a new issue, please take a moment to review our community guidelines to make the contribution process easy and effective for everyone involved.

You may find an answer in already closed issues:
https://github.com/AniTrend/retrofit-graphql/issues?q=is%3Aissue+is%3Aclosed

Feature Information

Currently we still use Library versions in buildSrc which we have to manually update using manesVersion to figure out available updates

Solution Information

Refer to this doc for additional context: https://docs.gradle.org/current/userguide/platforms.html also see example AniTrend/support-arch#88

Filtering of the log messages does not work

In response to the pull request #53:

Description Of Bug

The log messages are not filtered as expected when setting the Logger level.

Solution

The if statements of the form if(level < LogLevel.XXX) in the Logger object have to be swapped to if(level > LogLevel.XXX). The affected lines are 49, 61, 73, 85, 97 and 109. Would you like me to open a pull request again or will you change the lines yourself?

Not able to read Fragment from fragment package.

I created fragment in Fragment package but it getting the following issue
{"errors":[{"message":"Unknown fragment "ScoopFragment".","locations":[{"line":1,"column":771}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}},{"message":"Unknown fragment "ScoopFragment".","locations":[{"line":1,"column":1261}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}]}

assets/Fragment/ScoopFragment.graphql
fragment ScoopFragment on Scoop {
author
title
url
urlToImage
description
}
assets/Query/graph.graphql
query feed($limit: Int!) {
feed(limit: $limit) {
scoop{
...ScoopFragment
}

  }

}

Create custom converter with Moshi

I tried to create my own response converter with moshi instead of gson (more efficient and kotlin friendly) but no success.
I tried something like this :

override fun convert(responseBody: ResponseBody): T? {
    var response: T? = null
    if(type != null) {
        try {
            val responseString = responseBody.string()
            response = moshi.adapter<T>(getRawType(type)).fromJson(responseString)
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    return response
}

But I have this error :

Error for request No JsonAdapter for T (with no annotations)
for T data
for class io.github.wax911.library.model.body.GraphContainer
java.lang.IllegalArgumentException: No JsonAdapter for T (with no annotations)
for T data
for class io.github.wax911.library.model.body.GraphContainer

Do you know how to fix it ? Thanks !

Allow for Fragments to be defined in their own files.

Feature Information

I don't currently see a way to define GraphQL Fragments in their own files, and use (import) them within Queries. This would be great to have, as it can significantly cut down on query object/property duplication. This is a feature that Apollo has, but appears to be missing from this tool.

I am offering to take a stab at adding this feature via PR, if your team sees the value.

Solution Information

Having only been a user of your library, my (probably naive) idea to solve this would be to simply introduce a new sibling folder to the Mutation and Query folders, called Fragment.

It seems like the flow of logic would be to first check whether the Fragment is defined within the Query file first. If not, fallback to looking for the Fragment in the Fragment folder. The contents would be read, and appended to the original Query String before sending it to the server.

This might require a level of introspection into the Query that doesn't exist yet. I don't believe you guys currently validate that a Query has all of its dependent Fragments defined; letting the server handle that instead (correct?). So in order to avoid opening the door to really complicated query parsing logic (into structured data), perhaps the dependent fragments can be located via simple regex search? A similar strategy can be used to determine whether the Fragment already exists in the Query file, or if the logic should check the Fragment folder.

It seems really straight forward, but I fully acknowledge that I may be missing something. Thoughts?

An Example Scenario

Directory structure:

assets
  Mutation
  Query
    SomeQuery.graphql
  Fragment
    ObjectAFragment.graphql
    ObjectBFragment.graphql

SomeQuery.graphql:

query SomeQuery($id: ID!) {
  objectA(id: $id) {
      ... ObjectAFragment
  }
  objectB(id: $id) {
      ... ObjectBFragment
  }
}

ObjectAFragment.graphql:

fragment ObjectAFragment on ObjectA {
  id
  name
}

ObjectBFragment.graphql:

fragment ObjectBFragment on ObjectB {
  id
  name
}

Additional context

We recently switched from using Apollo to this library, and have loved it so far. We are just at the very beginning of migrating API calls over to use this library. And we have a ton of queries, and heavily use fragments that are separated out into their own files for reuse. We'd love to be able to contribute back!

Enable ProGuards Library not working

Have you defined progaurd rules for query for me name got change after enable progaurd, and i am not getting expected reslt.

Actual Query in Without Progaurd
{"extensions":{},"operationName":"feed","query":"query feed($limit: Int!, $fetchFrom: Long, $eventTypes: String, $profile: String, $group: Int) { feed(limit: $limit, fetchFrom: $fetchFrom, eventTypes: $eventTypes, profile: $profile, group: $group) { fetchFrom feed { type meta { type id body ref rating group { ...GroupFragment } image { ...ImageFragment } shares eventId profile { ...ProfileFragment } comments { id } createdAt editionId favorites isPrivate editorRawData hasUserFavorited previewImage{ ...ImageFragment } previewText views articleId readingTime scoop{ ...ScoopFragment } source { type meta { title type body ref createdAt updatedAt editionId edition { ...EditionFragment } profile { ...ProfileFragment } previewImage{ ...ImageFragment } previewText views articleId readingTime scoop{ ...ScoopFragment } } } edition { ...EditionFragment } isUserFollowingBook defaultCollection } } }}\n\nfragment ImageFragment on Image { baseUrl key}\n\nfragment GroupFragment on Group { id name avatar { ...ImageFragment } status}\n\nfragment ProfileFragment on Profile { avatar { ...ImageFragment } username displayName isFollowing }\n\nfragment ScoopFragment on Scoop { author title url urlToImage description source{ name } tags{ name slug }}\n\nfragment CoverFragment on EditionCover{ baseUrl key}\n\nfragment EditionFragment on Edition { title id description rating { edition average id count } type cover { ...CoverFragment } authors slug ISBN13 ISBNType createdAt}","variables":{"limit":10}}

Actual Query in After Progaurd

{"a":"feed","b":"query feed($limit: Int!, $fetchFrom: Long, $eventTypes: String, $profile: String, $group: Int) { feed(limit: $limit, fetchFrom: $fetchFrom, eventTypes: $eventTypes, profile: $profile, group: $group) { fetchFrom feed { type meta { type id body ref rating group { ...GroupFragment } image { ...ImageFragment } shares eventId profile { ...ProfileFragment } comments { id } createdAt editionId favorites isPrivate editorRawData hasUserFavorited previewImage{ ...ImageFragment } previewText views articleId readingTime scoop{ ...ScoopFragment } source { type meta { title type body ref createdAt updatedAt editionId edition { ...EditionFragment } profile { ...ProfileFragment } previewImage{ ...ImageFragment } previewText views articleId readingTime scoop{ ...ScoopFragment } } } edition { ...EditionFragment } isUserFollowingBook defaultCollection } } }}\n\nfragment ImageFragment on Image { baseUrl key}\n\nfragment GroupFragment on Group { id name avatar { ...ImageFragment } status}\n\nfragment ProfileFragment on Profile { avatar { ...ImageFragment } username displayName isFollowing }\n\nfragment ScoopFragment on Scoop { author title url urlToImage description source{ name } tags{ name slug }}\n\nfragment CoverFragment on EditionCover{ baseUrl key}\n\nfragment EditionFragment on Edition { title id description rating { edition average id count } type cover { ...CoverFragment } authors slug ISBN13 ISBNType createdAt}","c":{"limit":10},"d":{}}

File Uploading

how to work when i use multipart file uploading is thire any idea.

Drop minSdk to 17 again

In 90EC67F2 the minSdk version was changed from 17 to 21 due to changes in the Retrofit library.
The Retrofit README states: Retrofit requires at minimum Java 8+ or Android API 21+.

Since it is possible to use Retrofit 2.9.0 on Android < 5.0 by forcing to use OkHtpp 2.12.0 through:

implementation ('com.squareup.okhttp3:okhttp:3.12.0') {
    force = true
}

I think this library should stay on API 17. Any objections to that?

Automated Persisted Queries

Transparent support for Automated Persisted Queries (APQ) would be very useful. It makes queries smaller by sending a query id instead of the full query body, since there might be a size limit on HTTP POST bodies, or might cause performance problems when the body is large. It also allows clients to use HTTP GET instead of HTTP POST, making it easier to cache in a CDN (which might not allow caching of HTTP POST). The automated part is that the protocol allows clients to register new query id:s on the fly, so they do not have to be known by the server beforehand.

The protocol is simple:

  1. The client optimistically sends a query id instead of the query which is a sha256 hash of the query body.
  2. If the query id is not previously known by the server, the server sends a graphql error response with a PersistedQueryNotFound message
  3. The client then sends the full query body using HTTP POST, which the server then registers for future use

The full story is here: https://blog.apollographql.com/improve-graphql-performance-with-automatic-persisted-queries-c31d27b8e6ea

And the exact protocol is here:

https://github.com/apollographql/apollo-link-persisted-queries

This would be great if this was easy to enable by some configuration.

.graphql file isn't being detected

I followed the Getting Started guide to try this but the only way to get a response is to pass a QueryContainer reading the .graphql file instead of passing the builder with the @GraphQuery annotation

I checked the demo app and it's done the 'same' way the guide says. Tried moving GetMarketplaceListing.graphql to another dir and still worked. Renaming the file made stopped working.

This was tested on AVD API 30 and on a Redmi Note 5 Android 10.

NOT Working
MainActivity:

val query = QueryContainerBuilder().putVariable("idMal", 40060)
val anime = apiService.get(query)

ApiService (interface):

@POST("/graphql")
@GraphQuery("GetAnime")
suspend fun get(@Body builder: QueryContainerBuilder): Response<GraphContainer<Data>>

Body is null and the errorBody is 'Must provide query string'

Working
MainActivity:

val query = QueryContainerBuilder().setQuery(assets.open("graphql/queries/GetAnime.graphql").bufferedReader().readText())
.putVariable("idMal", 40060).build()
val anime = apiService.get(query)

ApiService (interface):

@POST("/graphql")
suspend fun get(@Body builder: QueryContainer): Response<GraphContainer<Data>>

This way the request is done fine and I get the data that I want.

GetAnime.graphql

query GetAnime($idMal: Int) {
    anime(idMal: $idMal) {
        id
        idMal
        idAl
    }
}

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.


Warning

Renovate failed to look up the following dependencies: Failed to look up maven package com.github.anitrend.support-arch:ui, Failed to look up maven package com.github.anitrend.support-arch:theme, Failed to look up maven package com.github.anitrend.support-arch:recycler, Failed to look up maven package com.github.anitrend.support-arch:extension, Failed to look up maven package com.github.anitrend.support-arch:domain, Failed to look up maven package com.github.anitrend.support-arch:data, Failed to look up maven package com.github.anitrend.support-arch:core, Failed to look up maven package com.github.anitrend.support-arch:analytics, Failed to look up maven package com.github.anitrend.support-arch:request, Failed to look up maven package com.github.anitrend.support-arch:paging-legacy, Failed to look up maven package com.github.anitrend.support-arch:recycler-paging-legacy, Failed to look up maven package com.github.anitrend.android-emojify:emojify, Failed to look up maven package com.github.anitrend.android-emojify:contract, Failed to look up maven package com.github.anitrend.android-emojify:kotlinx, Failed to look up maven package com.github.ChuckerTeam.Chucker:library, Failed to look up maven package com.github.ChuckerTeam.Chucker:library-no-op.

Files affected: gradle/libs.versions.toml


Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/android-spotless.yml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/gradle-build-action v3
.github/workflows/android-test.yml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/gradle-build-action v3
  • mikepenz/action-junit-report v4
.github/workflows/auto-approve.yml
  • hmarr/auto-approve-action v3
.github/workflows/first-contribution-greeting.yaml
  • actions/first-interaction v1
.github/workflows/gradle-dokka.yml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/gradle-build-action v3
  • JamesIves/github-pages-deploy-action v4.6.1
.github/workflows/gradle-wrapper-validation.yaml
  • actions/checkout v4
  • gradle/wrapper-validation-action v3
.github/workflows/release-builder.yml
  • actions/checkout v4
  • ericcornelissen/git-tag-annotation-action v1
.github/workflows/release-drafter.yml
  • release-drafter/release-drafter v6
  • peter-evans/repository-dispatch v3
.github/workflows/version-updater.yaml
  • actions/checkout v4
  • peter-evans/create-pull-request v6
gradle
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/module/Modules.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/CorePlugin.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/components/AndroidConfiguration.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/components/AndroidDependencies.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/components/AndroidOptions.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/components/AndroidPlugins.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/components/PropertiesComponent.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/extensions/DependencyHandlerExtensions.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/extensions/ProjectExtensions.kt
buildSrc/src/main/java/co/anitrend/retrofit/graphql/buildSrc/plugin/strategy/DependencyStrategy.kt
gradle.properties
settings.gradle.kts
build.gradle.kts
app/build.gradle.kts
buildSrc/settings.gradle.kts
buildSrc/build.gradle.kts
gradle/libs.versions.toml
  • com.jakewharton.threetenabp:threetenabp 1.4.7
  • com.jakewharton.timber:timber 5.0.1
  • junit:junit 4.13.2
  • com.android.tools.build:gradle 8.5.0
  • androidx.activity:activity 1.9.0
  • androidx.activity:activity-ktx 1.9.0
  • androidx.annotation:annotation 1.8.0
  • androidx.core:core 1.13.1
  • androidx.core:core-ktx 1.13.1
  • androidx.constraintlayout:constraintlayout 2.1.4
  • androidx.fragment:fragment 1.8.0
  • androidx.fragment:fragment-ktx 1.8.0
  • androidx.lifecycle:lifecycle-extensions 2.2.0
  • androidx.lifecycle:lifecycle-runtime 2.8.2
  • androidx.lifecycle:lifecycle-runtime-ktx 2.8.2
  • androidx.lifecycle:lifecycle-livedata 2.8.2
  • androidx.lifecycle:lifecycle-livedata-ktx 2.8.2
  • androidx.lifecycle:lifecycle-viewmodel 2.8.2
  • androidx.lifecycle:lifecycle-viewmodel-ktx 2.8.2
  • androidx.lifecycle:lifecycle-livedata-core 2.8.2
  • androidx.lifecycle:lifecycle-livedata-core-ktx 2.8.2
  • androidx.paging:paging-common-ktx 2.1.2
  • androidx.paging:paging-runtime 2.1.2
  • androidx.paging:paging-runtime-ktx 2.1.2
  • androidx.preference:preference-ktx 1.2.1
  • androidx.recyclerview:recyclerview 1.3.2
  • androidx.room:room-compiler 2.6.1
  • androidx.room:room-runtime 2.6.1
  • androidx.room:room-ktx 2.6.1
  • androidx.startup:startup-runtime 1.1.1
  • androidx.swiperefreshlayout:swiperefreshlayout 1.1.0
  • com.github.anitrend.support-arch:ui 1.7.7
  • com.github.anitrend.support-arch:theme 1.7.7
  • com.github.anitrend.support-arch:recycler 1.7.7
  • com.github.anitrend.support-arch:extension 1.7.7
  • com.github.anitrend.support-arch:domain 1.7.7
  • com.github.anitrend.support-arch:data 1.7.7
  • com.github.anitrend.support-arch:core 1.7.7
  • com.github.anitrend.support-arch:analytics 1.7.7
  • com.github.anitrend.support-arch:request 1.7.7
  • com.github.anitrend.support-arch:paging-legacy 1.7.7
  • com.github.anitrend.support-arch:recycler-paging-legacy 1.7.7
  • com.github.anitrend.android-emojify:emojify 1.9.1
  • com.github.anitrend.android-emojify:contract 1.9.1
  • com.github.anitrend.android-emojify:kotlinx 1.9.1
  • com.github.ChuckerTeam.Chucker:library 3.5.2
  • com.github.ChuckerTeam.Chucker:library-no-op 3.5.2
  • io.coil-kt:coil 2.6.0
  • io.coil-kt:coil-gif 2.6.0
  • com.google.android.material:material 1.12.0
  • org.jetbrains.dokka:dokka-gradle-plugin 1.9.20
  • org.jetbrains.kotlin:kotlin-stdlib-jdk8 2.0.0
  • org.jetbrains.kotlin:kotlin-reflect 2.0.0
  • org.jetbrains.kotlin:kotlin-gradle-plugin 2.0.0
  • org.jetbrains.kotlin:kotlin-serialization 2.0.0
  • org.jetbrains.kotlinx:kotlinx-coroutines-core 1.8.1
  • org.jetbrains.kotlinx:kotlinx-coroutines-android 1.8.1
  • org.jetbrains.kotlinx:kotlinx-coroutines-test 1.8.1
  • org.jetbrains.kotlinx:kotlinx-serialization-json 1.7.0
  • io.insert-koin:koin-core 3.5.6
  • io.insert-koin:koin-android 3.5.6
  • com.squareup.retrofit2:retrofit 2.11.0
  • com.squareup.retrofit2:converter-gson 2.11.0
  • com.squareup.okhttp3:okhttp 4.12.0
  • com.squareup.okhttp3:logging-interceptor 4.12.0
  • io.mockk:mockk 1.13.11
  • io.mockk:mockk-android 1.13.11
  • com.diffplug.spotless:spotless-plugin-gradle 6.25.0
  • com.pinterest:ktlint 1.0.1
library/build.gradle.kts
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.8

  • Check this box to trigger a request for Renovate to run again on this repository

Success and failure call back

Hello, Can you please help me achive the feature which we have in Completable class. It does have success, error, complete call back, how can I achive this using your library. I tried using Completable but it only supports Maybe, observer, completable types but using this library the return type of a network call is Response<GraphContainer<*>> which is not present in Completable class. End of the day I want to display the error message in UI if I get any error response, I am following the room architecture, UI layer ->Viewmodel -> Repository -> DAO . Please drop a mail if you don't want to talk this here ([email protected]) Thanks in advance, awaiting for you reply.

Request to change license to a more permissive one

This project appears to be using the GNU General Public License v3.0. This license is regarded infectious; any code that uses a GPL library automatically becomes GPL as well. Meaning any users of this library also need to disclose the source code of their application to the general public. A total dealbreaker for most commercial project.

Would it be possible to change the license to a more permissive one like Apache-2.0?

Dynamic Selection Set at Runtime

Question

Is there a way to modify the selection set of a query at runtime. I have a query where I have many possible selection sets based upon user input. I'm hoping to only have one query file for all of the iterations because it's a complicated query and only a small portion of the selection set gets modified.

I also wouldn't mind if there is a way to manually create the query via strings. I notice that QueryContainerBuilder has a setQuery function which would work, but after reading the code it seems that this function is actually an internal function that gets overriden?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.