Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve server side GraphQL support for spring-graphql and Nextflix DGS #2856

Merged
merged 21 commits into from
Aug 3, 2023

Conversation

adinauer
Copy link
Member

@adinauer adinauer commented Jul 20, 2023

📜 Description

We already have basic support for graphql-java and Netflix DGS. This PR adds on top of that:

  • More exceptions and errors caught and reported to Sentry by also looking at the ExecutionResult (more specifically its errors)
  • More details for Sentry events
    • Query, variables and response (where possible)
  • Breadcrumbs for operation (query, mutation, subscription), data fetchers and data loaders (Spring only)
  • Better hub propagation by using GraphQLContext

💡 Motivation and Context

Fixes #2790

💚 How did you test it?

Please take a look at the sample code to see that inputs cause which errors.

Queries used

Netflix DGS queries

Shows

{
    shows {
        id
        title
        releaseYear
    }
}

New shows

{
    newShows {
        id
        title
        releaseYear
        iDoNotExist
    }
}

Mutation

mutation AddShowMutation($title: String!) {
    addShow(title: $title)
}

variables:

{
    "title": "A new show"
}

Subscription

subscription SubscriptionNotifyNewShow($releaseYear: Int!) {
  notifyNewShow(releaseYear: $releaseYear) {
    id
    title
    releaseYear
  }
}

variables:

{
  "releaseYear": -1
}

Data loader

query QueryShows {
    shows {
        id
        title
        releaseYear
        actorId
        actor {
            id
            name
        }
    }
}
Spring queries

Greeting

{
    greeting(name: "crash")
}

Greeting with variables

Sample events:

query GreetingQuery($name: String) {
    greeting(name: $name)
}

variables:

{
    "name": "crash"
}

Project

Sample events:

query ProjectQuery($slug: ID!) {
    project(slug: $slug) {
        slug
        name
        repositoryUrl
        status
    }
}

variables:

{
    "slug": "statuscrash"
}

Mutation

Sample events:

mutation AddProjectMutation($slug: ID!) {
    addProject(slug: $slug)
}

variables:

{
    "slug": "nocrash",
    "name": "nocrash"
}

Subscription

Sample events:

subscription SubscriptionNotifyNewTask($slug: ID!) {
    notifyNewTask(projectSlug: $slug) {
        id
        name
        assigneeId
        assignee {
            id
            name
        }
    }
}

variables:

{
    "slug": "crash"
}

Data loader

Sample events:

query TasksAndAssigneesQuery($slug: ID!) {
    tasks(projectSlug: $slug) {
        id
        name
        assigneeId
        assignee {
            id
            name
        }
    }
}

variables:

{
    "slug": "crash"
}

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

  • more manual testing
  • copy spring changes to spring-jakarta
  • add automated tests
  • mark internal classes

@github-actions
Copy link
Contributor

github-actions bot commented Jul 20, 2023

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 8cf8f57

if (result != null) {
@NotNull Response response = new Response();
Map<String, Object> responseBody = result.toSpecification();
response.setData(responseBody);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you set all the information besides the data?

Copy link
Member Author

Choose a reason for hiding this comment

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

You mean statuscode, headers and cookies?

Copy link
Member Author

Choose a reason for hiding this comment

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

I can probably attach some of it for Spring in an event processor but since the response isn't finished yet it might very well be wrong / incomplete. Would you still like me to add it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add it after the request is made? This does not need to be GraphQL-specific since it makes sense for every integration.

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you add it after the request is made?

I don't understand. Do you mean after the response is finished? We'd have to delay sending an event to Sentry, probably put the response stuff on the scope and pick it up from there once ready. Sounds brittle and complicated.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, after the request is "finished".
I don't know the internals to tell how complicated is, but we do that with transactions and spans right, we collect all the information and "capture" at the end once everything is figured out, maybe we need something similar.
It's not a must but wishable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Can we do this in a follow up PR?

import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Flux;

public final class SentryDgsSubscriptionHandler implements SentrySubscriptionHandler {
Copy link
Member Author

Choose a reason for hiding this comment

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

put this here as it requires reactor. If we added reactor to sentry-graphql we could rename it to something generic and put it there. Not sure we should do that tho.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 20, 2023

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 329.88 ms 384.78 ms 54.91 ms
Size 1.72 MiB 2.29 MiB 575.70 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
3baa73f 267.45 ms 388.30 ms 120.85 ms
9246ed4 281.79 ms 352.08 ms 70.29 ms
2718fc8 322.33 ms 369.98 ms 47.65 ms
f274c79 313.96 ms 355.96 ms 42.00 ms
4c237f8 319.84 ms 354.47 ms 34.63 ms
4bf202b 364.28 ms 419.66 ms 55.38 ms
dc67004 273.86 ms 346.37 ms 72.51 ms
496bdfd 301.22 ms 343.96 ms 42.73 ms
8820c5c 330.60 ms 416.86 ms 86.26 ms
f60279b 324.60 ms 345.33 ms 20.73 ms

App size

Revision Plain With Sentry Diff
3baa73f 1.72 MiB 2.29 MiB 575.52 KiB
9246ed4 1.72 MiB 2.28 MiB 572.22 KiB
2718fc8 1.72 MiB 2.29 MiB 575.53 KiB
f274c79 1.72 MiB 2.29 MiB 575.01 KiB
4c237f8 1.72 MiB 2.29 MiB 575.58 KiB
4bf202b 1.72 MiB 2.29 MiB 575.54 KiB
dc67004 1.72 MiB 2.28 MiB 573.45 KiB
496bdfd 1.72 MiB 2.28 MiB 571.82 KiB
8820c5c 1.72 MiB 2.28 MiB 571.82 KiB
f60279b 1.72 MiB 2.29 MiB 575.23 KiB

Previous results on branch: feat/improved-graphql-server-support

Startup times

Revision Plain With Sentry Diff
7c99037 297.06 ms 362.04 ms 64.98 ms
2702851 295.00 ms 366.50 ms 71.50 ms
93f6eb8 293.06 ms 327.16 ms 34.10 ms
1412898 344.34 ms 382.63 ms 38.29 ms
dbb5dc4 331.08 ms 352.98 ms 21.90 ms

App size

Revision Plain With Sentry Diff
7c99037 1.72 MiB 2.29 MiB 575.54 KiB
2702851 1.72 MiB 2.29 MiB 575.54 KiB
93f6eb8 1.72 MiB 2.29 MiB 575.54 KiB
1412898 1.72 MiB 2.29 MiB 575.54 KiB
dbb5dc4 1.72 MiB 2.29 MiB 575.54 KiB

@marandaneto
Copy link
Contributor

Just nitpick, for later, missing null annotations, and final fields.
Can you add some sentry issue links with some examples and/or screenshots?

@codecov
Copy link

codecov bot commented Jul 25, 2023

Codecov Report

Patch coverage: 43.82% and project coverage change: -0.95% ⚠️

Comparison is base (4c237f8) 81.39% compared to head (8cf8f57) 80.45%.
Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2856      +/-   ##
============================================
- Coverage     81.39%   80.45%   -0.95%     
- Complexity     4652     4701      +49     
============================================
  Files           354      371      +17     
  Lines         17134    17556     +422     
  Branches       2314     2364      +50     
============================================
+ Hits          13947    14125     +178     
- Misses         2237     2454     +217     
- Partials        950      977      +27     
Files Changed Coverage Δ
...y/spring/boot/jakarta/SentryAutoConfiguration.java 97.14% <0.00%> (-1.41%) ⬇️
...io/sentry/spring/boot/SentryAutoConfiguration.java 97.14% <0.00%> (-1.41%) ⬇️
...ing/jakarta/graphql/SentryBatchLoaderRegistry.java 0.00% <0.00%> (ø)
...hql/SentryDataFetcherExceptionResolverAdapter.java 0.00% <0.00%> (ø)
.../jakarta/graphql/SentryDgsSubscriptionHandler.java 0.00% <0.00%> (ø)
...akarta/graphql/SentryGraphqlBeanPostProcessor.java 0.00% <0.00%> (ø)
...ng/jakarta/graphql/SentryGraphqlConfiguration.java 0.00% <0.00%> (ø)
...ntry/spring/graphql/SentryBatchLoaderRegistry.java 0.00% <0.00%> (ø)
...hql/SentryDataFetcherExceptionResolverAdapter.java 0.00% <0.00%> (ø)
...y/spring/graphql/SentryDgsSubscriptionHandler.java 0.00% <0.00%> (ø)
... and 15 more

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@adinauer adinauer marked this pull request as ready for review July 27, 2023 08:28
@adinauer adinauer requested a review from sentrivana July 28, 2023 10:59
Copy link
Member Author

@adinauer adinauer left a comment

Choose a reason for hiding this comment

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

@sentrivana I marked what I think makes sense to take a look at with 👀 for you. Feel free to review more if you feel like it ;-)

@sentrivana
Copy link

@sentrivana I marked what I think makes sense to take a look at with 👀 for you. Feel free to review more if you feel like it ;-)

Thanks for prescreening things :) I will take a look later today or on Monday.

Copy link
Collaborator

@lbloder lbloder left a comment

Choose a reason for hiding this comment

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

LGTM, except for some nitpicks :)

Also, extending existing READMEs or adding one on how to call the graphql endpoints in the samples might be nice

@adinauer adinauer merged commit fb296f0 into main Aug 3, 2023
18 of 20 checks passed
@adinauer adinauer deleted the feat/improved-graphql-server-support branch August 3, 2023 10:53
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.

[java] GraphQL Connected Services
4 participants