-
Notifications
You must be signed in to change notification settings - Fork 2k
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
extensions #657
Comments
Apollo Server supports the tracing and cache control extensions by default. We would like to expose a plugin API for adding extensions, but for now you can use Which sort of extension are you interested in? |
Ah, ok. Thanks, that is enough for me then. |
The extension use case I was looking into was validating that a query was no more than N deep. So for example, you allowed clients to only nest 4 levels deep with each query. You'd parse the query into an AST, validate & then throw an error if >4. |
@martijnwalraven why not adding a extensions options besides the tracing options. A simple array would suffice. Would you guys accept a PR? |
@ruiaraujo You can already use |
I was aware of that repo since i check the implementation of the apollo tracing. I wanted to instrument the same way but use internal metrics. What I can do with formatResponse is to extract it from the extensions but it seems a round about way of going at it. The GraphQLExtension class seems pretty good for my needs. |
@rcrowe I think it's not the role of the extension but the role of the validationRule to parse the query into an AST and validate it. You could compute the deepness of the query by parsing each OperationDefinition and its selectionSet. |
I also want to add my own extensions, but there's no way to actually implement a real extension (like TracingExtension and CacheControlExtension) and have apollo-server use it. |
Would it be possible to take custom extensions from the configuration options (similar to what express-graphql does)? Do something like this?
An extension seems straight forward to implement. (unless i have missed something) https://github.com/apollographql/apollo-tracing-js/blob/master/src/index.ts
|
When batching, am I right in thinking these extensions run for each query? If so, Do we also need something similar at a request, rather than query level? For context, my use-cases are metrics/tracing. For example, I'd like metrics for both query duration and request duration. Currently I can attach a correlation ID at a request level, which gets propagated via Thinking about it, what I'm interested in is less 'GraphQL extensions' and more 'extending Apollo to add instrumentation'. Sorry if I hijacked this thread, please feel free to point me somewhere else/open a new issue if appropriate 🙂 |
@ThomWright Yes, they run for each request. Whether the naming makes sense depends on how you view batching. One way of looking at it is that batching is a transport-level optimization to put multiple GraphQL requests in a single HTTP request. When you use Apollo Engine, transport batching is actually of limited use, because Engine supports HTTP/2 even when your server doesn't. That means you can run multiple GraphQL requests in parallel over a single HTTP connection, without blocking (which is one of the downsides of transport batching). What is your use case for performing your own metrics/tracing? Have you looked at using Apollo Tracing and Engine? |
Yeah I've looked at Apollo Tracing and Engine, they simply don't fit nicely into our existing monitoring infrastructure. Right now I'm reluctant to add more 'infrastucture' just for GraphQL, I'd much prefer to consolidate where possible. Saying that, I expect Apollo Engine provides extra value beyond what we're trying to do, so we might consider it as a complementary system at some point. For metrics we're using Prometheus, and I'd like to be able to collect metrics such as request durations and error counts. Since we're batching, per-query would be useful. For tracing (with correlation IDs) our use case is logging, but we might also consider implementing something like OpenTracing in future (I see this is already being discussed here apollographql/apollo-tracing#12). Again, per-query would be useful. I hope this helps, let me know if you'd like more info. |
I also want to add my own extensions 😋 |
As stated allowing custom extensions is the way forward and better approach than doing in formatResponse or anything else. Since we were also interested in instrumenting our code, a simple solution we have been using for long time is to hijack sample code is here import { LogAction, LogMessage, LogStep } from "apollo-server-core";
function traceQuery(): (message: LogMessage) => void {
const initTime = process.hrtime();
// Initialise the start times of all LogActions
const startTimes = {
[LogAction.request]: initTime,
[LogAction.parse]: initTime,
[LogAction.validation]: initTime,
[LogAction.execute]: initTime
};
return message => {
const { action, step } = message;
switch (step) {
case LogStep.start:
startTimes[action] = process.hrtime();
break;
case LogStep.end:
// metricName = LogAction[action]
// duration = process.hrtime(startTimes[action])
break;
default:
// discard status step
break;
}
};
} Hope this helps 😄 , PS: Its really not a good approach as it is relying on the internals of |
Here's an initial (I guess) PR #934 which enable us to support additional extensions 🍻. |
I'm working on this! |
The new request pipeline in #1795 brought with it a new generation of extension points, most all of which are intended to replace hooks that were never officially supported in the undocumented The new plugins cover a wider-range of life-cycles than just those of the request, including the server startup time. We feel that this API will be a more sustainable API in the long run, but we're certainly looking for feedback on it, as we want to make sure it covers all the use-cases prior to sunsetting The new plugin API is documented within #2008 at the moment, so please do give it a look and try it out (both the documentation and the plugin API, please!). Additionally, for a concrete example of a functioning plugin, take a look at the Thanks! |
Are extensions not supported?
The text was updated successfully, but these errors were encountered: