-
Notifications
You must be signed in to change notification settings - Fork 13
Integration issues #62
Comments
I think we could make this work, yeah. For default cases, I think GrAMPS working standalone makes sense, so I don't think I'd want to change that API (especially because breaking changes this early on seem ill-advised). However, I think we could easily abstract out the core parts of GrAMPS into named exports, so you could do something like this: import { generateExecutableSchema } from 'gramps';
const gramps = generateExecutableSchema();
const schema = gramps.schema;
// do whatever you want
app.use('/graphql', graphqlExpress({
schema: finalSchema,
context: req => ({
req,
gramps: gramps.context(req),
}),
// additional options...
})); Were you thinking the |
^^ to clarify, |
And where would I pass in my GrAMPS datasources in this example? Also, as the function does not return just the executable schema, maybe you can call it |
Regarding the context, that depends on where you 'need' it to be. I see in your example you pass it in on the top level, so you would have (in apollo) Maybe you could expose an actual middleware function too, so I don't have to do: app.use((req, res, next) => {
req.gramps = gramps.context(req)
next()
} But could instead do: app.use(gramps.contextMiddleware) |
It would have the same API as We could refactor under the hood so that Data sources scope context in resolvers to their own namespace + the content of const gramps = prepare({
dataSources: [/* ... */],
extraContext: {
// any extra context needed by GrAMPS data sources goes here
},
}); |
See my proposal (very initial version, no linting, tests, or even running). I don't think there's an issue with |
So, to recap, that would mean you could alternatively do (keeping the existing API 100% intact): import { prepare } from 'gramps'
const gramps = prepare({ /* all gramps() parameters here */ })
const schema = gramps.schema
// do my own stuff with my schemas
app.use('/graphql', gramps.contextMiddleware)
// do my own stuff in the context
app.use('/graphql', graphqlExpress({ schema: finalSchema, context: req => req, /* additional options */ }) Looking at this code sample, |
This seems most descriptive to my eye: app.use('/graphql', gramps.addContext); As long as the existing API stays intact, I think this is a solid addition for advanced use cases. |
As |
I threw together a quick boilerplate, for use with
As you can see in the resulting index file, this now integrates perfectly with the existing (best practice) server boilerplates and the other tools. |
This is awesome. Thank you! |
This is a totally different take on a solution, but let me know what you think @kbrandwijk. If what you need is the resulting // gramps.js
const middleware = req => ({
schema,
context: getContext(req),
...apolloOptions.graphqlExpress,
});
middleware.schema = schema;
middleware.getContext = getContext;
return middleware; Then you can use them however you'd like. import gramps from 'gramps'
const middleware = gramps({ /* all gramps() parameters here */ });
const { schema, getContext } = middleware;
// do my own stuff with my schemas
app.use('/graphql', middleware)
// do my own stuff in the context
app.use('/graphql', graphqlExpress({ schema: finalSchema, context: req => req, /* additional options */ }) |
@ecwyne Although technically allowed in JS, the signature of what Also, for type safety in TS, it would result in a typing declaration that uses declaration merging in order to work, which I also try to avoid usually. function middleware(req: express.Request): ApolloServerOptions { }
namespace middleware {
// schema and getContext here;
} |
I'm inclined to agree: adding props to functions has always looked hacky to me, and I think it increases the cognitive overhead of understanding what's going on. |
After having a good look at the getting started and the sources, I'd like to share a few integration issues that I've come across. Basically the biggest issue is the fact that the output from
gramps()
goes directly into the apollo-server middleware. I thought I could get around it by accessing the individual properties of that object (for example, the schema), but that's also not possible, because the output is actually a function ofreq
. Of course, I can work around that as well, by runninggramps()(null).schema
to get to the schema, but that doesn't really feel right.This means that I end up with an all or nothing solution, which is not really what I would like. I'd like to have the ability to composition these components into my own server.
To be able to do this I need the following:
This might be as easy as:
Now, if I didn't need all of that, I would still be able to do:
So it wouldn't impact the getting-started experience much, but would make it a lot easier to either use it in a more mixed environment, or integrate it with other tools (like
graphql-yoga
and my upcomingsupergraph
framework).The text was updated successfully, but these errors were encountered: