Skip to content

[feature/chucker-gql] GQL support against latest develop #800

Closed
alkber wants to merge 10 commits into
ChuckerTeam:developfrom
alkber:feature/chucker-gql
Closed

[feature/chucker-gql] GQL support against latest develop #800
alkber wants to merge 10 commits into
ChuckerTeam:developfrom
alkber:feature/chucker-gql

Conversation

@alkber

@alkber alkber commented Apr 18, 2022

Copy link
Copy Markdown

There was already an old implementation done here . This PR seems to be old one (2019) and way out of sync with develop branch. I have refactored it to meet the latest changes.

This almost getting ready and not the final PR yet, need to get valuable input on the code quality and optimization if required.

Sample Activity has also been provided for the demo

Known Issues
Couldn't successfully run the sample until i commented this part of the code

//        StrictMode.setVmPolicy(
//            StrictMode.VmPolicy.Builder()
//                .detectLeakedClosableObjects()
//                .penaltyLog()
//                .penaltyDeath()
//                .build()
//        )
//
//        StrictMode.setThreadPolicy(
//            StrictMode.ThreadPolicy.Builder()
//                .detectDiskReads()
//                .detectDiskWrites()
//                .penaltyLog()
//                .penaltyDeath()
//                .build()
//        )

@MiSikora MiSikora left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For a PR that introduces integration with a new specification, there are no tests. Please cover necessary scenarios such as GET and POST requests with ChuckerInterceptor as both application and network interceptor.

It would be also helpful if you could follow our PR template. Screenshots especially would be appreciated.

Status.Failed -> " ! ! ! $method $path"
Status.Requested -> " . . . $method $path"
else -> "$responseCode $method $path"
else -> "$responseCode $method $path ${isGraphqlRequest.takeIf { true } ?: ""}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is always true.

Comment on lines +87 to +95
gqlVisibiltyGroup.visibility = if (transaction.isGqlRequest) {
transaction.gqlOperationName?.let { opName ->
setGqlInfo(
operationName = opName,
ProtocolResources.Gql()
)
View.VISIBLE
} ?: View.GONE
} else View.GONE

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For a piece of code that deals with visibility, It is very hard to understand what is going on here. Please refactor it.

Comment on lines +29 to +33
val countriesQuery = "query countries {\n" +
" countries {\n" +
" name\n" +
" }\n" +
"}\n"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please use raw strings. Preferably trimMargin() variant.


internal interface GraphQLSWApi {
@POST("/")
@Headers("Content-Type: application/json")

@MiSikora MiSikora Apr 18, 2022

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it necessary? GsonConverterFactory should add this header on its own.

internal interface GraphQLSWApi {
@POST("/")
@Headers("Content-Type: application/json")
fun getCountries(@Body body: GraphQLResponseBody?): Call<Any?>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The body doesn't have to be nullable.

Comment on lines +68 to +71
} else {
decodedContent?.let { content ->
transaction.gqlOperationName = inferGqlRequest(content)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think it is correct to have it in the else clause here. It indicates that having the GraphQL operation name is somehow related to reaching the request threshold.

)

internal interface GraphQLSWApi {
@POST("/")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would like to have an example of a GET request if possible.

client: OkHttpClient,
) : HttpTask {

private val api = Retrofit.Builder()

@MiSikora MiSikora Apr 18, 2022

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think that the vast majority of people will use GraphQL with something like Apollo. I would prefer to see a real-life scenario integration within our sample instead of Retrofit.

}
}.firstOrNull()

private fun inferGqlRequest(body: String): String? {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Inferring GraphQL from a body won't work for GET requests as there is only URL query parameter for those.

It's a bit hard to have a full-proof solution as anyone could have query parameters or bodies that conform to GraphQL format. I have an idea of how to deal with it but let's just first implement handling of GET requests as well.

Comment on lines +143 to +144
val isGraphqlRequest: Boolean
get() = !gqlOperationName.isNullOrEmpty()

@MiSikora MiSikora Apr 18, 2022

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This doesn't seem right. The operationName is an optional parameter in GraphQL. I think we can rely solely on query. Plus there is an additional issue for GET requests, which I mentioned here.

@MiSikora

Copy link
Copy Markdown
Contributor

Known Issues Couldn't successfully run the sample until i commented this part of the code

//        StrictMode.setVmPolicy(
//            StrictMode.VmPolicy.Builder()
//                .detectLeakedClosableObjects()
//                .penaltyLog()
//                .penaltyDeath()
//                .build()
//        )
//
//        StrictMode.setThreadPolicy(
//            StrictMode.ThreadPolicy.Builder()
//                .detectDiskReads()
//                .detectDiskWrites()
//                .penaltyLog()
//                .penaltyDeath()
//                .build()
//        )

I experienced it in the past as well but I thought that #750 fixed it.

@MiSikora MiSikora dismissed their stale review April 21, 2022 18:37

I'm retracting my review because I don't know how GH behaves after I remove myself from maintainers, and I don't want to lock this PR

@cortinico

Copy link
Copy Markdown
Member

Sorry for the late reply here.
I've noticed we do have another similar PR here: #805
I'd like to understand which of the two we prefer to move forward.

@alkber

alkber commented May 5, 2022

Copy link
Copy Markdown
Author

Please close this PR in respect of a better implementation at https://github.com/ChuckerTeam/chucker/pull/805

@cortinico

Copy link
Copy Markdown
Member

Please close this PR in respect of a better implementation at https://github.com/ChuckerTeam/chucker/pull/805

👍 We'll keep the disucssion going on #805

@cortinico cortinico closed this May 6, 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.

3 participants