Skip to content

Add support for GraphQL#70

Closed
rnitame wants to merge 17 commits into
ChuckerTeam:developfrom
rnitame:feature/graphql-support
Closed

Add support for GraphQL#70
rnitame wants to merge 17 commits into
ChuckerTeam:developfrom
rnitame:feature/graphql-support

Conversation

@rnitame

@rnitame rnitame commented Jul 25, 2019

Copy link
Copy Markdown

fix #69

Screenshot_1567082567

@rnitame rnitame changed the title Add support for GraphQL wip: Add support for GraphQL Jul 25, 2019
@rnitame rnitame changed the title wip: Add support for GraphQL Add support for GraphQL Jul 27, 2019

@cortinico cortinico left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you be able to provide a sample public endpoint to include inside the Sample app?

val content = io.readFromBuffer(buffer, charset, maxContentLength)
transaction.requestBody = content
transaction.operationName =
Gson().fromJson(content, HttpRequestBody::class.java).operationName

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be really inefficient :(
You're going to recreate a Gson instance for every request.
Please use a JsonConvertor.getInstance().

}

data class HttpRequestBody(
val operationName: String?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GSON annotation is missing here.

private val UTF8 = Charset.forName("UTF-8")
}

data class HttpRequestBody(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming can be improved here:

Suggested change
data class HttpRequestBody(
data class GraphQLRequestBody(

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the location of operation name was different depending on the library, it was absorbed using JsonParser

apollo-android :

{
  "operationName": "xxx"
}

retrofit-graphql :

{
  "queryContainer" : {
       "operationName": "xxx"
   }
}

Status.Failed -> " ! ! ! $method $path"
Status.Requested -> " . . . $method $path"
else -> responseCode.toString() + " " + method + " " + path
else -> responseCode.toString() + " " + method + " " + path + if (isGraphql) operationName else ""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a space between path and operation name?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

@rnitame rnitame force-pushed the feature/graphql-support branch from 6f5f74e to e4f0fa5 Compare August 3, 2019 04:33
@rnitame rnitame force-pushed the feature/graphql-support branch from a9e78bb to 151c570 Compare August 3, 2019 06:57
@rnitame

rnitame commented Aug 5, 2019

Copy link
Copy Markdown
Author

@cortinico Thanks for your comments!

Would you be able to provide a sample public endpoint to include inside the Sample app?

I added implementation using SWApi. http://graphql.org/swapi-graphql/ :)
Please review again.

val key = "operationName"
if (content.has(key)) return content.get(key).asString

return if (content.has("queryContainer")) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @rnitame
Apparently here there is a problem. GraphQL request should have the operationName at the top level and should not be wrapped inside a queryContainer object:

Screenshot_1565099160

This is an invalid GraphQL request.

The problem is caused by the initialisation of the retrofit interface:

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://graphql.org")
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

Although we could fix it by using the Converter factory provided by retrofit-graphql, I think it's better if we change approach here.

Can I ask you to:

a) Don't use retrofit-graphql. Is yet another dependency that we probably don't need.
b) Just create a simple data class and do a GraphQL request without external library (as described here: https://graphql.org/learn/serving-over-http/#post-request)
c) Remove all the .graphql file?

@cortinico cortinico added this to the 3.1.0 milestone Aug 11, 2019
@cortinico

Copy link
Copy Markdown
Member

Let me know when this is ready for review again :)

@rnitame rnitame force-pushed the feature/graphql-support branch from dc949d9 to f85fac9 Compare August 29, 2019 12:50
@rnitame rnitame force-pushed the feature/graphql-support branch from ab298b1 to 5bbecf9 Compare September 11, 2019 11:39
@rnitame rnitame force-pushed the feature/graphql-support branch from 5bbecf9 to b4814b8 Compare September 11, 2019 11:52
@psh psh mentioned this pull request Sep 15, 2019
Comment on lines +82 to +83
object : TypeToken<GraphQLRequestBody>() {
}.type

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use this trick

// Somewhere smart in the lib
inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
// Usage
genericType<GraphQLRequestBody>()

Comment on lines +113 to +115
operationName.setText(transaction.getOperationName());
operationName.setVisibility(transaction.isGraphQL() ? View.VISIBLE : View.GONE);
graphql.setVisibility(transaction.isGraphQL() ? View.VISIBLE : View.GONE);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All those lines are about GraphQL, can do something to group them ?

if (transaction.isGraphQL()) {
    operationName.setText(transaction.getOperationName());
    operationName.setVisibility(View.VISIBLE);
    graphql.setVisibility(View.VISIBLE);
}

And set them to View.GONE by default.

Comment thread sample/build.gradle
Comment on lines +39 to +42
repositories {
maven { url 'https://jitpack.io' }
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the repository in /build.gradle instead? Under allprojects.repositories.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, why do we need this repository? Can we just remove it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, this can be removed entirely

cache(30).enqueue(cb)
}

with(SampleApiService.getGraphQLInstance(getClient(this))) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method getClient doesn't only get the HTTP client, it also create it. It should be named buildHttpClient or something, it would explicitly show that something is built by this method. And maybe we shouldn't abuse of calls to this method.

Comment thread sample/build.gradle
Comment on lines +39 to +42
repositories {
maven { url 'https://jitpack.io' }
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, this can be removed entirely

Comment thread sample/proguard-rules.pro
-dontwarn okio.**
-dontwarn retrofit2.**

# retrofit-graphql

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this


<uses-permission android:name="android.permission.INTERNET" />

<uses-sdk tools:overrideLibrary="io.github.wax911.library" />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this

android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#e535ab"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please export this color

Call<Void> cache(@Path("seconds") int seconds);
}

interface GraphQLSWApi {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this to a separate class, like a SimpleGraphQLService or something similar

@vbuberen

Copy link
Copy Markdown
Collaborator

@rnitame
Could you give some timeline on when you plan to finish this PR?

I would love to proceed with 3.1.0 release in some nearest time, so if it would take too much time we might need to postpone it to 3.2.0.

Agree @cortinico @olivierperez ?

@cortinico

Copy link
Copy Markdown
Member

I would love to proceed with 3.1.0 release in some nearest time, so if it would take too much time we might need to postpone it to 3.2.0.

Agree @cortinico @olivierperez ?

Definitely, let's move this to 3.2.0 👍

@cortinico cortinico modified the milestones: 3.1.0, 3.2.0 Jan 16, 2020
@vbuberen

Copy link
Copy Markdown
Collaborator

@rnitame @cortinico
Hey guys, could someone provide some info on the status of this feature and what is required to make it to production?
Is any help or discussion required?

@vbuberen

Copy link
Copy Markdown
Collaborator

Also, let's consider points from #116 here.
Probably, it is better to outline some plan with help of @psh to improve implementation as much as we can?

@cortinico

Copy link
Copy Markdown
Member

Probably, it is better to outline some plan with help of @psh to improve implementation as much as we can?

Agree here. I generally like the approach in this PR by @rnitame. I believe we could reuse the UI part at least.

On the other hand I believe GraphQL initialisation should be provided by the developer when creating the ChuckerInterceptor, rather than having the library trying to infer if a request is actually a valid GraphQL request. So on that side we should probably change our approach.

transaction.requestContentLength = requestBody?.contentLength() ?: 0L

val encodingIsSupported = io.bodyHasSupportedEncoding(request.headers().get("Content-Encoding"))
val encodingIsSupported =

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it didn't change content. Can be reverted to reduce the diff.


if (requestBody != null && encodingIsSupported) {
val source = io.getNativeSource(Buffer(), io.bodyIsGzipped(request.headers().get("Content-Encoding")))
val source = io.getNativeSource(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here.

@quentin41500

quentin41500 commented Mar 4, 2020

Copy link
Copy Markdown

This is such a nice feature! Anyway I can help getting that merge? I'm not the branch owner so I don't think I can push to it, but I could make a new branch with the desired changes if that's ok.

Let me know!

@cortinico

Copy link
Copy Markdown
Member

This is such a nice feature! Anyway I can help getting that merge? I'm not the branch owner so I don't think I can push to it, but I could make a new branch with the desired changes if that's ok.

Let me know!

You can definitely send a new PR branching from this one :)

@vbuberen

vbuberen commented Mar 5, 2020

Copy link
Copy Markdown
Collaborator

@quentin41500 That is actually cool. I believe that you could cooperate with @rnitame to do a new version of PR.

Also, I would like to join you in these efforts, since from what I see there were not much attention to this PR and it is quite old already, while the feature is really useful. So ping me here or in Chucker Slack channel and let's make it happen in 3.2.0 😄

@cortinico

Copy link
Copy Markdown
Member

Closing this one as we have two other PRs achieving the same 👍
Let's look into merging those.

Thanks for your time @rnitame

@cortinico cortinico closed this Sep 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for GraphQL

6 participants