-
Notifications
You must be signed in to change notification settings - Fork 24
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
bump to @apollo/server v4 #574
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,26 +32,21 @@ | |
"author": "Daniel Schmidt <[email protected]>", | ||
"license": "MIT", | ||
"peerDependencies": { | ||
"apollo-server": ">=3.0.0", | ||
"apollo-server-env": "*", | ||
"@apollo/server": ">=4.0.0", | ||
"graphql": ">=0.10.x", | ||
"opentracing": "*" | ||
}, | ||
"dependencies": { | ||
"apollo-server-plugin-base": "^3.0.0", | ||
"apollo-server-types": "^3.0.0" | ||
}, | ||
"devDependencies": { | ||
"@apollo/server": "4.5.0", | ||
"@commitlint/config-conventional": "11.0.0", | ||
"@commitlint/travis-cli": "11.0.0", | ||
"@types/jest": "26.0.24", | ||
"@types/node": "14.18.38", | ||
"@types/supertest": "2.0.12", | ||
"all-contributors-cli": "6.24.0", | ||
"apollo-server": "3.12.0", | ||
"apollo-server-env": "4.2.1", | ||
"express": "4.18.2", | ||
"graphql": "15.8.0", | ||
"body-parser": "^1.20.2", | ||
"graphql": "16.6.0", | ||
"graphql-tools": "6.2.6", | ||
"jest": "27.5.1", | ||
"opentracing": "0.14.7", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
import * as express from "express"; | ||
import * as request from "supertest"; | ||
import { ApolloServer } from "apollo-server-express"; | ||
import { ApolloServer } from "@apollo/server"; | ||
import { expressMiddleware } from '@apollo/server/express4'; | ||
import { json } from 'body-parser'; | ||
import { Tracer } from "opentracing"; | ||
import { MockSpan, MockSpanTree } from "../test/types"; | ||
import spanSerializer from "../test/span-serializer"; | ||
import ApolloOpentracing, { InitOptions, SpanContext } from "../"; | ||
import ApolloOpentracing, { InitOptions } from "../"; | ||
|
||
expect.addSnapshotSerializer(spanSerializer); | ||
|
||
|
@@ -147,16 +149,18 @@ class MockTracer { | |
} | ||
} | ||
|
||
async function createApp<InstanceContext extends SpanContext>({ | ||
interface EmptyContext {} | ||
|
||
async function createApp({ | ||
tracer, | ||
...params | ||
}: { tracer: MockTracer } & Omit< | ||
InitOptions<InstanceContext>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this passed as a generic? |
||
InitOptions<EmptyContext>, | ||
"server" | "local" | ||
>) { | ||
const app = express(); | ||
|
||
const server = new ApolloServer({ | ||
const server = new ApolloServer<EmptyContext>({ | ||
typeDefs: ` | ||
type A { | ||
one: String | ||
|
@@ -221,12 +225,12 @@ async function createApp<InstanceContext extends SpanContext>({ | |
], | ||
}); | ||
await server.start(); | ||
server.applyMiddleware({ app }); | ||
app.use('/graphql', json(), expressMiddleware(server)); | ||
|
||
return app; | ||
} | ||
|
||
describe("integration with apollo-server", () => { | ||
describe("integration with @apollo/server", () => { | ||
it("closes all spans", async () => { | ||
const tracer = new MockTracer(); | ||
const app = await createApp({ tracer }); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,16 @@ | ||
import { Span } from "opentracing"; | ||
import { GraphQLResolveInfo, ResponsePath } from "graphql"; | ||
import { GraphQLRequestContext } from "apollo-server-plugin-base"; | ||
import { ContextForApolloOpenTracing, WithRequiredSpanContext, hasSpanContext, addSpanContext } from './index'; | ||
|
||
/** | ||
* Object containing private methods that this library uses, that will be attatched to the GQL context object. | ||
* (Will be namespaced using a symbol to hide this from users) | ||
*/ | ||
export interface SpanContext { | ||
getSpanByPath(info: ResponsePath): Span | undefined; | ||
addSpan(span: Span, info: GraphQLResolveInfo): void; | ||
} | ||
|
||
function isArrayPath(path: ResponsePath) { | ||
return typeof path.key === "number"; | ||
} | ||
|
@@ -19,40 +29,23 @@ export function buildPath(path: ResponsePath | undefined) { | |
return segments.reverse().join("."); | ||
} | ||
|
||
export interface SpanContext extends Object { | ||
_spans: Map<string, Span>; | ||
getSpanByPath(info: ResponsePath): Span | undefined; | ||
addSpan(span: Span, info: GraphQLResolveInfo): void; | ||
// Passed in from the outside context | ||
requestSpan?: Span; | ||
} | ||
|
||
function isSpanContext(obj: any): obj is SpanContext { | ||
return ( | ||
obj.getSpanByPath instanceof Function && obj.addSpan instanceof Function | ||
); | ||
} | ||
|
||
export function requestIsInstanceContextRequest<CTX extends SpanContext>( | ||
request: GraphQLRequestContext<CTX | Object> | ||
): request is GraphQLRequestContext<CTX> { | ||
return isSpanContext(request.context); | ||
} | ||
|
||
// TODO: think about using symbols to hide these | ||
export function addContextHelpers(obj: any): SpanContext { | ||
if (isSpanContext(obj)) { | ||
return obj; | ||
export function addContextHelpers<Context extends ContextForApolloOpenTracing>( | ||
contextValue: Context | ||
): WithRequiredSpanContext<Context> { | ||
if (hasSpanContext(contextValue)) { | ||
return contextValue; | ||
} | ||
|
||
obj._spans = new Map<string, Span>(); | ||
obj.getSpanByPath = function (path: ResponsePath): Span | undefined { | ||
return this._spans.get(buildPath(isArrayPath(path) ? path.prev : path)); | ||
}; | ||
|
||
obj.addSpan = function (span: Span, info: GraphQLResolveInfo): void { | ||
Comment on lines
-49
to
-53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is I don't see it referenced in README.md, other than:
(I've interpreted the latter given |
||
this._spans.set(buildPath(info.path), span); | ||
const spans = new Map<string, Span>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why was this attached to the context object? (closure here means it's no longer exposed) |
||
const spanContext: SpanContext = { | ||
getSpanByPath: (path: ResponsePath): Span | undefined => { | ||
return spans.get(buildPath(isArrayPath(path) ? path.prev : path)); | ||
}, | ||
addSpan: (span: Span, info: GraphQLResolveInfo): void => { | ||
spans.set(buildPath(info.path), span); | ||
}, | ||
}; | ||
|
||
return obj; | ||
addSpanContext(contextValue, spanContext); | ||
return contextValue; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was contradicted by L117