express-graphql-server
v0.1.0
Published
A GraphQL server based on Apollo Server and Express.js
Downloads
41
Maintainers
Readme
Express GraphQL Server
Node.js GraphQL server based on Apollo Server and Express.js
Installation
npm install express-graphql-server
API
const createServer = require("express-graphql-server");
const apiServer = createServer(options);
// or using a one-liner:
// const apiServer = require("express-graphql-server")(options);
createServer (options)
Create a GraphQL server with the passed options
and
return an object that exposes a start()
and a call(fn)
method.
Options
The options
object passed to createServer
has the following properties:
serverConfig {Object}: For configuring the HTTP server.
host
{String} (Default:'localhost'
)port
{Number} (Default:3001
)allowedOrigins
{Array}: For CORS. Requests from hosts not specified in the array will be rejected (Default:['localhost']
).Important: To be able to test your GraphQL server or make requests to it from the online GraphQL playground during development, add "https://studio.apollographql.com" to the list of allowed origins.
https
{Boolean}: If true, serve requests over HTTPS (Default:false
).cacheBackend
{Object}: The cache backend used by ApolloServer. (Default is a newInMemoryLRUCache
instance). See this link on Configuring Apollo Cache Backends for more.sslPrivateKey
{Buffer|String}: The private key to use for HTTPS. (Defaults to an empty string). This is required (cannot be empty) ifserverConfig.https
is set totrue
.sslPublicCert
{Buffer|String}: The public certificate (fullchain) to use for HTTPS. (Defaults to an empty string). Required ifserverConfig.https
is set totrue
.sslVerifyCertificates
{Boolean} (Default:false
).trustProxy
{Boolean} (Default:false
): If we are behind a proxy, we can set this totrue
.secureCookies
{Boolean} (Default:false
): Iftrue
, cookies are served only over an HTTPS connection.
sessionConfig {Object}: For configuring [
express-session
][].name
{String}: Name of the session ID cookie, defaults toconnect.sid
.secret
{Array|String}: Secret for signing the session ID cookie.expiry
{Number}: The session expiration time (in minutes) (Default:0
).createStore
{Function}: A function that should return anexpress-session
-compatible session store instance. The function receives anexpress-session
instance as its first argument. (Defaults to a newMemoryStore
instance).express-graphql-server
comes with an implementation that returns a Redis store instance. The implementation usesredis-mock
in test and development environments, and usesredis
otherwise. If you plan to use Redis as a session store, you can use the included Redis store implementation as is in development and testing. If you plan to use it in production or staging environments, you will need to have a Redis instance configured and running.See the examples folder and the Example section for how to use it.
schema {Array} [required]: GraphQL schema definition strings
resolvers {Object} [required]: GraphQL resolvers
context {Function|Object}: Allows you to pass in arbitrary values to the context object. These values must be encoded in a key-value object. The passed values will be available to every resolver via the
context
argument available to all resolvers.context
can be either an object or a function. If it is a function, the function automatically receives a context object as an argument. The function must return a key-value object as specified above.setup {Function}: Initialization function for performing arbitrary setup tasks. At the time of invoking the function, the request body can be accessed via
req.body
but the session has not been initialized. We are thus still able to edit or modify the [express-session
][] options.Inside this function, we can, for example, register middleware that's not dependent on session data being available. The Example section demonstrates how to use this to implement a remember user feature.
The function receives an object with the following members:
app
: The app instance (const app = express()
)sessionConfig
: The read-write session configuration options forexpress-session
.
Check the examples directory for usage examples.
ExpressGraphQLServer
methods
createServer(options)
returns a promise that resolves to an instance of ExpressGraphQLServer
.
In the example code above, we assigned this object instance to the apiServer
variable.
The object exposes the following methods:
apiServer.start(): Start the GraphQL server running on the specified host and port. The method returns a promise that resolves to an object with the following members:
app
: The underlying Express App (const app = express()
).httpServer
: The underlying Node.js HTTP server (const server = http(s).createServer()
)graphqlServer
: The underlying Apollo (GraphQL) Server instance (const server = new ApolloServer()
).
apiServer.call(callback): Allows us to execute arbitrary code such as registering middlewares or custom (non-graphql) routes that need to access session data to the Express app after the session has been initialized but prior to starting the server. The
callback
receives as argument an object with the following members:app
: An instance of Express app (const app = express()
).
If we are using this function for registering a middleware, we must call to
app.use(middlewareFn)
from within thecallback
passing it the middleware function as argument:apiServer.call(function({ app }) { app.use(function middlewareName(req, res, next) { // Perform middleware actions here // make sure to call next() to pass on the request to the next middleware in the chain // and avoid terminating the request next(); }); });
Example
const expressGraphQLServer = require("express-graphql-server");
const schema = require("path/to/your/schema");
const resolvers = require("path/to/your/resolvers");
// These (with the exception of `studio.apollographql.com`)
// are the default `serverConfig` values when none is supplied
const serverConfig = {
host : "localhost",
port : 3001,
allowedOrigins : ["http://localhost", "https://studio.apollographql.com"],
https : false,
sslPrivateKey : "",
sslPublicCert : "",
sslVerifyCertificates : false,
trustProxy : false,
secureCookies : false,
};
const sessionConfig = {
name: "connect.sid",
store: null, // use MemoryStore instance in development
secret: "some secret string",
expiry: 0
};
/* To use the included Redis store implementation for `sessionConfig.createStore`,
* you can use this code:
*/
/*
const { createRedisFactory } = require("express-graphql-server");
const redisFactory = createRedisFactory({
host: REDIS_HOST,
port: REDIS_PORT,
onConnect: () => console.log("Successful connection to Redis!"),
onError: (err) => console.warn("Redis connection error"),
});
sessionConfig.createStore = redisFactory;
*/
(async function runServer() {
// Create the server
const apiServer = await expressGraphQLServer({
serverConfig,
sessionConfig,
schema,
resolvers,
context: null,
setup: function onCreate({ app, sessionConfig }) {
// Use a middleware to implement a "remember user" feature
const REMEMBER_USER_FOR = 30; // number of days to remember user for
return (req, res, next) => {
if(req.body.query?.indexOf("mutation login") === 0) {
if(req.body.variables?.rememberUser) {
sessionConfig.rolling = false;
sessionConfig.cookie.maxAge = (
1000 * 60 * 60 * 24 * Number(REMEMBER_USER_FOR)
);
}
}
// Remember to call `next()`
// so that the request can be passed on to the next middleware in the chain
next();
};
}
});
// Start the server
const { app, httpServer, graphqlServer } = await apiServer.start();
}());
Running the included examples
You can find some examples inside the examples directory.
To run the examples,
- Ensure you have a database instance running.
- Navigate to the
examples/<TARGET_EXAMPLE>
directory, e.g:cd examples/user-management-system
. - Copy the
.env.example
file inside the directory to a.env
file inside the same directory and edit the environment variable values as appropriate, making sure theDATABASE_URL
value matches your database connection details. - Copy the
src/prisma/schema.prisma.example
file tosrc/prisma/schema.prisma
and edit as appropriate. - If you are using MongoDB, note the following:
- prisma requires a MongoDB replica set. You can use the open source mongo-db-replica-set for running the examples.
- Edit the
src/prisma/schema.prisma
file as follows:- In the
datasource db
section, set theprovider
field value to"mongodb"
. - For the
id
fields of the models, changedbgenerated()
(which is not allowed with MongoDB) toauto()
.
- In the
- If this is the first time you are running the given example, do the following:
- run
npm install
to install the required dependencies. - If you are using MongoDb, run
npm run prisma:generate
to generate the prisma client, otherwise runnpm run prisma
to perform the database migration as well as generate the prisma client.
- run
- Run
npm start
to start the server lisening onAPP_HOST:APP_PORT
, whereAPP_HOST
andAPP_PORT
are the values set inside the.env
file. - Send GraphQL queries to
APP_HOST:APP_PORT/graphql
.
To view and edit database data in the browser, run npm run prisma:studio
from within the target example directory, then using your browser, navigate to localhost:5555
.
Running the tests
- Run
npm test
to run tests - Run
npm run test:coverage
to run tests with code coverage reporting