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

The deduplicator now accepts a query param #312

Closed
wants to merge 7 commits into from

Conversation

lfades
Copy link
Contributor

@lfades lfades commented May 11, 2018

Custom headers are deprecated (also read this issue).

This is not a breaking change, a header will still work but now the docs show the usage with the query param ?deduplicate instead.

As a side note: I ran the script format and some code that's not related to this change was modified according to Prettier rules

README.md Outdated
@@ -128,7 +128,7 @@ The `options` object has the following fields:
| `uploads` | [UploadOptions](/src/types.ts#L39-L43) or `false` or `undefined` | `null` | Provides information about upload limits; the object can have any combination of the following three keys: `maxFieldSize`, `maxFileSize`, `maxFiles`; each of these have values of type Number; setting to `false` disables file uploading |
| `https` | [HttpsOptions](/src/types.ts#L62-L65) or `undefined` | `undefined` | Enables HTTPS support with a key/cert
| `getEndpoint` | String or Boolean | `false` | Adds a graphql HTTP GET endpoint to your server (defaults to `endpoint` if `true`). Used for leveraging CDN level caching. |
| `deduplicator` | Boolean | `true` | Enables [graphql-deduplicator](https://github.com/gajus/graphql-deduplicator). Once enabled sending the header `X-GraphQL-Deduplicate` will deduplicate the data. |
| `deduplicator` | Boolean | `true` | Enables [graphql-deduplicator](https://github.com/gajus/graphql-deduplicator). Once enabled sending the query param `?deduplicate` will deduplicate the data. |
Copy link
Contributor

Choose a reason for hiding this comment

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

How about this?

Once enabled, adding ?deduplicate to endpoint URL will deduplicate the data.

body: { query },
}).promise()

const deduplicatedWithHeader = await request({
Copy link
Contributor

@kachkaev kachkaev May 11, 2018

Choose a reason for hiding this comment

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

It might be useful to state why the test is here. Others might be surprised seeing it despite that the docs don't mention X-GraphQL-Deduplicate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, a comment can make it more clear

src/index.ts Outdated
@@ -185,7 +185,8 @@ export class GraphQLServer {
}
return (response, ...args) => {
if (
req.get('X-GraphQL-Deduplicate') &&
(req.get('X-GraphQL-Deduplicate') ||
req.query.deduplicate !== undefined) &&
Copy link
Contributor

@kachkaev kachkaev May 11, 2018

Choose a reason for hiding this comment

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

I'd check against req.query.deduplicate first given that this is now a preferred method. Perhaps, a comment about the legacy support of X-GraphQL-Deduplicate can be helpful too.

I'm also wondering if there is a cheap way to be a bit smarter with handling the value. It'd be great to consider ?deduplicate, ?deduplicate=true and ?deduplicate=1 as true, while treat any other value as false. I'd be also great if this check could be later reused for graphql-crunch too (#303).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd like such restriction for other values and it should be very simple to check.

})

t.deepEqual(deduplicated, deduplicatedWithHeader)

t.deepEqual(body.data, inflate(deduplicated.data))
Copy link
Contributor

Choose a reason for hiding this comment

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

If neither of deduplications worked, will the test pass?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, that one is just to check that both are the same, to check that data is properly deduplicated there's another check above

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, sure! I somehow missed t.deepEqual above 😅

src/index.ts Outdated
@@ -184,8 +183,11 @@ export class GraphQLServer {
return this.options.formatResponse
}
return (response, ...args) => {
const truthyValues = ['', '1', 'true']
Copy link
Contributor

@kachkaev kachkaev May 11, 2018

Choose a reason for hiding this comment

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

Could this array be initialised once rather than at every request? It'd be probably useful to name it a bit more explicitly if moving elsewhere, say to trulyValuesForQueryParameter. I'm also wondering if '' would be the value for ?deduplicate just like in the case of ?deduplicate=. Can't check this now, but could the first case produce null? I'm also not sure that ?deduplicate= should be treated as true, to me this is like ?deduplicate=false.

It'd be nice to add a test with a non-truly value (e.g. ?deduplicate=false) to make sure we're not accidentally deduplicating at all times. If we turn a check into a function, it may be easier to unit-test and reuse with ?crunch in future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

?deduplicate and ?deduplicate= are the same (''), I think we can treat both as true or only allow ?deduplicate=true and ?deduplicate=1, otherwise we'll need to do another check

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Basically we can do something like this:

function isTrulyQueryParam(value: string) {
  return value === '1' || value === 'true'
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd go for treating ?deduplicate, ?deduplicate=, ?deduplicate=true and ?deduplicate=1 as true then. I guess people would want to use http://example.com/graphql?deduplicate – it looks pretty clean.

Copy link
Contributor

@kachkaev kachkaev May 17, 2018

Choose a reason for hiding this comment

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

/**
 * Normalises GET param values into a boolean.
 * Returns true in the following cases:
 * ?param ?param= ?param=1 ?param=true
 */
function isTrulyQueryParam(value: string) {
  return value === '' || value === '1' || value === 'true'
}

@lfades
Copy link
Contributor Author

lfades commented May 18, 2018

This PR is ready to be merged now 💃

@kachkaev
Copy link
Contributor

kachkaev commented Jun 7, 2018

ping @timsuchanek / @schickling 😉

@stale
Copy link

stale bot commented Nov 23, 2018

Due to inactivity of this issue we have marked it stale. It will be closed if no further activity occurs.

@stale stale bot added the stale label Nov 23, 2018
@stale
Copy link

stale bot commented Nov 30, 2018

Hey 👋, It seems like this issue has been inactive for some time. In need for maintaining clear overview of the issues concerning the latest version of graphql-yoga we'll close it.
Feel free to reopen it at any time if you believe we should futher discuss its content. 🙂

@stale stale bot closed this Nov 30, 2018
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.

2 participants