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

Use HeaderMap instead of plain Map for headers #7313

Merged
merged 2 commits into from Jan 18, 2023

Conversation

vtipparam
Copy link
Contributor

The expressMiddleware handler uses a plain Map for the headers that results in case sensitive lookup on the headers. This makes the header Apollo-Query-Plan-Experimental ineffective when the ApolloServer is used with expressMiddleware handler.

Resolves apollographql/federation#2337

@netlify
Copy link

netlify bot commented Jan 18, 2023

Deploy Preview for apollo-server-docs ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 9cd9f38
🔍 Latest deploy log https://app.netlify.com/sites/apollo-server-docs/deploys/63c87266226c300008698183
😎 Deploy Preview https://deploy-preview-7313--apollo-server-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jan 18, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 9cd9f38:

Sandbox Source
Apollo Server Typescript Configuration
Apollo Server Configuration

@trevor-scheer
Copy link
Member

Thanks for the PR! Would you please add a changeset by running npx changeset (just a patch since this is a bugfix).

@trevor-scheer trevor-scheer merged commit ec28b4b into apollographql:main Jan 18, 2023
@github-actions github-actions bot mentioned this pull request Jan 18, 2023
trevor-scheer pushed a commit that referenced this pull request Jan 19, 2023
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @apollo/server-integration-testsuite@4.3.1

### Patch Changes

- [#7285](#7285)
[`35fa72bdd`](35fa72b)
Thanks [@glasser](https://github.com/glasser)! - Adds an integration
test verifying that Rover's introspection query works. This should not
break any integration that passes other tests.

- [#7276](#7276)
[`15c912f4c`](15c912f)
Thanks [@renovate](https://github.com/apps/renovate)! - Update
graphql-http dependency

- Updated dependencies
\[[`ec28b4b33`](ec28b4b),
[`322b5ebbc`](322b5eb),
[`3b0ec8529`](3b0ec85)]:
    -   @apollo/server@4.3.1

## @apollo/server@4.3.1

### Patch Changes

- [#7313](#7313)
[`ec28b4b33`](ec28b4b)
Thanks [@vtipparam](https://github.com/vtipparam)! - Allow case
insensitive lookup on headers. Use HeaderMap instead of plain Map for
headers in expressMiddleware.

- [#7311](#7311)
[`322b5ebbc`](322b5eb)
Thanks [@axe-me](https://github.com/axe-me)! - Export intermediate
ApolloServerOptions\* types

- [#7274](#7274)
[`3b0ec8529`](3b0ec85)
Thanks [@patrick91](https://github.com/patrick91)! - The subgraph spec
has evolved in Federation v2 such that the type of
`_Service.sdl` (formerly nullable) is now non-nullable. Apollo Server
now
    detects both cases correctly in order to determine whether to:
    1.  install / enable the `ApolloServerPluginInlineTrace` plugin
2. throw on startup if `ApolloServerPluginSchemaReporting` should not be
installed
3. warn when `ApolloServerPluginUsageReporting` is installed and
configured with the `__onlyIfSchemaIsNotSubgraph` option

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@glasser
Copy link
Member

glasser commented Jan 19, 2023

Huh! @trevor-scheer do you understand why this wasn't a compilation failure?

The field HTTPGraphQLRequest.headers is defined to be a HeaderMap, and class HeaderMap extends Map<string, string>. Does TypeScript interpret this as meaning that headers can be anything that has the public API of HeaderMap (which doesn't include anything more than Map) I guess? I didn't realize that...

@glasser
Copy link
Member

glasser commented Jan 19, 2023

Yeah I suppose so: https://www.typescriptlang.org/docs/handbook/2/classes.html#relationships-between-classes

Do we want to make some change here (somehow compatibly?) to make this issue less possible?

@vtipparam
Copy link
Contributor Author

Huh! @trevor-scheer do you understand why this wasn't a compilation failure?

I was wondering about that as well. Magic of Duck Typing in Typescript?

@trevor-scheer
Copy link
Member

Yeah, maybe some additional property on the HeaderMap will give us the differentiation we're expectingto have.

trevor-scheer added a commit that referenced this pull request Jan 19, 2023
Related: #7313

This shouldn't have been allowed by the typings in the first place.
Previously, a `Map` was compatible with `HeaderMap` according to
TypeScript, so the error wasn't a typing error (when we wanted it to
be). Adding an arbitrary class property to the `HeaderMap` class gives
us the typing error we'd expect when a `Map` is used in lieu of a
`HeaderMap`.
@theJC
Copy link

theJC commented Feb 25, 2023

FYI, any of the apollo-server-integrations until each one has switched over to use HeaderMap AND cuts a new release, consumers will likely still be using case-sensitve map for headers.

  1. At Indeed we use Koa, and therefore we use apollo-server-integration-koa. We hit this case sensitive header issue, but fortunately we got lucky that this was fixed by @trevor-scheer in chore(deps): update all non-major dependencies apollo-server-integrations/apollo-server-integration-koa#84 -- but we didnt have access to this fix until fortunately release v0.3.0 was cut a few days ago (I believe for other reasons) and allowed us to pull in the fix to this issue.

  2. The hapi integration looks to still be using new Map(): https://github.com/apollo-server-integrations/apollo-server-integration-hapi/blob/f9ef226df0dcb3d8ebf2189629dd368c6b6b2d9b/src/index.ts#L99 and may still have this issue.

  3. Maybe all the integrations need to be reviewed to make sure this is corrected for everyone, and releases get cut rather than waiting for significant other changes to be made to finally get a release cut.

  4. Should there/is there a plan to make sure best practices/important changes information (like this one) that is made in the built-in express middleware is disseminated so that all the frameworks fix the same issue if they are effected?

@trevor-scheer
Copy link
Member

Hey @theJC. These integrations are intentionally (somewhat) disparate and community-owned, so while at some level I help maintain them in a pinch / as-needed, the hope is that community members who are interested in both Apollo Server and their respective framework of choice maintain them, respond to issues, etc. It's not a perfect system but I do keep an eye on them and step in if needed.

That being said - we do export an integration testsuite and typings which act as a guide for integration authors to stay in step with expected behaviors. As long as authors keep their dev dependencies up-to-date, use TypeScript, and run our testsuite in CI, we can reasonably expect things should be working as intended.

In the specific HeaderMap case, this was ultimately a typings issue which slipped through the cracks. The fix I landed here is a good example of how we disseminate important changes (in this case through typings) - so as the integrations update their dependencies, they should see a new error if applicable.

The important part for this to work is that we remain vigilant with appropriate testsuite additions and typings fixes as applicable. This is imperfect, but it's pretty good. And to be fair to this project, AS4 has successfully made these integrations very simple and the pattern repeatable so overall I'm not too worried about this being a recurring or frequent problem.

If you see any places where we can improve this process or have anything in mind, I'd be happy to hear ideas! And if you'd like to participate / help improve any of the integrations you're of course invited to do so.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Setting the header Apollo-Query-Plan-Experimental has no effect
4 participants