type-graphql
type-graphql copied to clipboard
More examples
- [x] integration with apollo-engine (
apollo-cache-control
) - [x] usage with mongoose (
typegoose
) - [x] usage on client side (Apollo client state)
- [x] using class mixins
- [x] GraphQL Modules
- [ ] Join Monster
- [ ] graphql-shield integration
- [ ] using relations betweens types (user -> recipes -> comments)
- [ ] testing examples (unit and e2e)
- [ ] AWS lambda (
apollo-server-lambda
) - [ ] sample fullstack project with React and Apollo
Please add some examples with apollo-server package. especially apollo-server-express and apollo-server-lambda
Usage of apollo-server-express
is the same as in its repository readme:
import express from 'express';
import bodyParser from 'body-parser';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import { buildSchema } from "type-graphql";
async function bootstrap() {
// the only different part
const myGraphQLSchema = await buildSchema({
resolvers: [__dirname + "/**/*.resolver.ts"],
});
const PORT = 3000;
const app = express();
// bodyParser is needed just for POST.
app.use('/graphql', bodyParser.json(), graphqlExpress({ schema: myGraphQLSchema }));
app.get('/graphiql', graphiqlExpress({ endpointURL: '/graphql' })); // if you want GraphiQL enabled
app.listen(PORT);
}
bootstrap();
apollo-server-lambda
usage looks the same as the only demand is to provide schema myGraphQLSchema = require('./schema');
so you might need to use buildSchemaSync
function. However it's more complicated so I will try create an AWS free tier and try the lambda 😉
@19majkel94 thank you it works. This is just brilliant. I actually have found a way to integrate with injection-js as well. Hope this will be released soon. Actually you don't need to create an aws account. You can try it with serverless framework and serverless-offline plugin to emulate lambda environment at your local machine.
@sandangel how did you get this working with aws lambda? I'm having some issues as lined out in #96
import 'reflect-metadata';
import { graphiqlExpress, graphqlExpress } from 'apollo-server-express';
import * as serverless from 'aws-serverless-express';
import bodyParser from 'body-parser';
import cors from 'cors';
import express from 'express';
import { Server } from 'http';
import { buildSchemaSync, useContainer } from 'type-graphql';
import { Container } from 'typedi';
import { AuthResolver, MobileDataResolver, MobileKitResolver } from './resolvers';
import { authChecker } from './utils/auth-checker';
/**
* Must be called before build schema or Resolver won't inject the Service
*/
useContainer(Container);
/**
* Lambda gonna build schema for each request lead to duplicate GraphQL Declaration
* so we need to cache the built schema.
* (this is currently the default cache for type-graphql too)
* @type {GraphQLSchema}
*/
(<any>global).schema =
(<any>global).schema ||
buildSchemaSync({
resolvers: [AuthResolver, MobileKitResolver, MobileDataResolver],
authChecker
});
export const app = express();
export const schema = (<any>global).schema;
export let cachedServer: Server;
export function bootstrapServer() {
app.use('/graphql', cors(), bodyParser.json(), (req, res, next) => {
const token = req.headers.authorization;
graphqlExpress({ schema, context: { token } })(req, res, next);
});
app.get('/', graphiqlExpress({ endpointURL: '/graphql' }));
return serverless.createServer(app);
}
export const graphqlHandler = (event, context) => {
if (cachedServer == null) {
console.log('Bootstrapping server...');
const server = bootstrapServer();
cachedServer = server;
return serverless.proxy(server, event, context);
} else {
console.log('Using cached server...');
return serverless.proxy(cachedServer, event, context);
}
};
@darbio The problem is that the metadata is attached to global scope to make multi-packages work but AWS lambda use the same node.js process for each request, so consecutive schema builds effect in duplicated types&resolvers definition.
Storing built schema in global
fix that + save time that would be used to build the schema for each request.
OK. I saw that in the code above, however I get the following error when I try and use the global scoped metadata. I've confirmed that I am only including type-grahql
and not any other graphql
packages.
Error: Cannot use GraphQLSchema "[object Object]" from another module or realm.
Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.
https://yarnpkg.com/en/docs/selective-version-resolutions
Duplicate "graphql" modules cannot be used at the same time since different
versions may have different capabilities and behavior. The data from one
version used in the function from another could produce confusing and
spurious results.
at instanceOf (/Users/jamesdarbyshire/Repositories/darb.io/cad/cad-api/.webpack/service/src/index.js:28689:13)
at isSchema (/Users/jamesdarbyshire/Repositories/darb.io/cad/cad-api/.webpack/service/src/index.js:35013:35)
at validateSchema (/Users/jamesdarbyshire/Repositories/darb.io/cad/cad-api/.webpack/service/src/index.js:35287:25)
at assertValidSchema (/Users/jamesdarbyshire/Repositories/darb.io/cad/cad-api/.webpack/service/src/index.js:35312:16)
at Object.validate (/Users/jamesdarbyshire/Repositories/darb.io/cad/cad-api/.webpack/service/src/index.js:43344:35)
at doRunQuery (/Users/jamesdarbyshire/Repositories/darb.io/cad/cad-api/.webpack/service/src/index.js:892:38)
at /Users/jamesdarbyshire/Repositories/darb.io/cad/cad-api/.webpack/service/src/index.js:803:56
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
Is there any code samples for e2e tests?
@codingmaven A lot of in tests folder 😄
const query = `{
myQuery {
myField
}
}`;
const { data } = await graphql(schema, query);
expect(data!.myQuery.myField).toEqual("myFieldValue");
@19majkel94 do you have any testing examples with typeorm?
@RodolfoSilva Just use the dependency injection (TypeDI) and data mapper patter (repository) as in the typeorm-typegraphql examples here on repo. Then you can easily mock the object passed to the constructor in unit test to stub the DB access.
Hi there, would like to add +1 request to AWS Lambda example because it has been very annoying to set up this to work there.
I have this repository (https://github.com/ramonpm/typescript-serverless-graphql) running and working fine with serverless offline
. However, once I deploy it to AWS lambda, I get this error
Unable to import module 'handler': Error
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.source-map-support (/var/task/handler.js:29922:18)
at __webpack_require__ (/var/task/handler.js:20:30)
at Object../source-map-install.js (/var/task/handler.js:29722:1)
at __webpack_require__ (/var/task/handler.js:20:30)
at Object.0 (/var/task/handler.js:29733:1)
at __webpack_require__ (/var/task/handler.js:20:30)
Which is probably due to externals: [nodeExternals()],
in my webpack.config.js but if I don't use that it fails badly with Error: Cannot use GraphQLSchema "[object GraphQLSchema]" from another module or realm
Thought about creating a new issue, but I noticed they have being closed pointing to this issue...
@ramonpm here is a working version that I setup https://github.com/causecode/type-graphql-typegoose-serverless
And another set of examples at https://github.com/kirill578/type-graphql-serverless-example
Thank you @visheshd
It turned out that for some reason I don't really care I had to use --useSeparateProcesses
to run it locally without the conflicts. Should I care :sweat_smile: though ?
Apollo server lambda is an example I would really appreciate seeing today.
Can we add Azure Functions to that list @MichalLytek? I would be able to provide a working example the following days.