AniTrend / retrofit-graphql

Retrofit converter which uses annotations to inject .graphql query or mutation files into a request body, along with any variables.
https://anitrend.github.io/retrofit-graphql/
Apache License 2.0
109 stars 19 forks source link

.graphql file isn't being detected #119

Closed LetrixZ closed 3 years ago

LetrixZ commented 3 years ago

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
    }
}
wax911 commented 3 years ago

Hi, are you sure that the .graphql file isn't being detected? Can you check the logcat as you make the request you should find the following output:

"The requested query annotated with value: `GetAnime` could not be found!"

If the file isn't found

LetrixZ commented 3 years ago

I wasn't getting any output, so I added this to my Retrofit builder:

addConverterFactory(GraphConverter(GraphProcessor(AssetManagerDiscoveryPlugin(assetManager = context.assets),logger = DefaultGraphLogger(ILogger.Level.VERBOSE)), Gson()))

Output:

V/GraphProcessor: main: has obtained a synchronized lock on the object
V/GraphProcessor: main: is initializing query files
V/GraphProcessor: main: has completed initializing all graphql files
V/GraphProcessor: main: discovered `1` graphql files

Running this I can get the first line of the file:

assets.open("GetAnime.graphql").bufferedReader().readLine()
wax911 commented 3 years ago

From the small snipet you have provided it looks like the file is found but at runtime somethings seems to be off, I have tried the sample project with the default converter: GraphConverter(...) just to be sure that the issue isn't coming from there and that seems to be working fine, can you please provide a full log filtered by GraphProcessor from the startup of your application to the point after you get the error Must provide query string

LetrixZ commented 3 years ago

I'm trying on another project and the same issue. This is all the logging I have and I only receive only those 4 lines from GraphProcessor. MainActivity$onCreate is where I called it using CoroutineScope(Dispatchers.IO).launch logcat.txt

wax911 commented 3 years ago

Just out of curiosity, what does your assets folder structure look like, and do you mind sharing your second demo sample so I can take a look?

LetrixZ commented 3 years ago

This is the project I'm working it right now: https://github.com/LetrixZ/miranime assets folder ApiService Interface Retrofit Builder

In the meantime, I'm using Apollo without problems.

wax911 commented 3 years ago

I think I found your problem, in provideApiService

    .addConverterFactory(GraphConverter.create(context, ILogger.Level.VERBOSE))
    .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))

Swap the order of graph converter and gson converter, otherwise retrofit will default to the Gson and you should see more loggs

2021-04-01 12:02:32.146 9534-9534/com.letrix.miranime V/GraphProcessor: main: has obtained a synchronized lock on the object
2021-04-01 12:02:32.146 9534-9534/com.letrix.miranime V/GraphProcessor: main: is initializing query files
2021-04-01 12:02:32.154 9534-9534/com.letrix.miranime V/GraphProcessor: main: has completed initializing all graphql files
2021-04-01 12:02:32.154 9534-9534/com.letrix.miranime V/GraphProcessor: main: discovered `3` graphql files
2021-04-01 12:02:32.250 9534-9569/com.letrix.miranime D/GraphProcessor: Looking up `.graphql` file matching: GetHome.graphql

N.B GraphConverter has factory methods to initialise everything you need e.g. GraphConverter.create(context, ILogger.Level.VERBOSE)

If you need GsonConverterFactory for some other endpoints you could simply extend GraphConverter and override requestBodyConverter to provide a different converter for anything else that is not annotated with GraphQuery on the methodAnnotations

LetrixZ commented 3 years ago

It worked! Thanks :)