We can create a simple GraphQL server with Express. To do this, we need the express-graphql
and graphql
packages.
In this article, we’ll look at how to use middleware with Express GraphQL.
Express Middleware
We can use Express middlewares as usual if we use express-graphql
to build our GraphQL server with Express.
The request
object is available as the second argument in any resolver.
For example, if we want to get the hostname of a request in our resolver, we can write:
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');
const schema = buildSchema(`
type Query {
hostname: String
}
`);
const loggingMiddleware = (req, res, next) => {
console.log(req.hostname);
next();
}
const root = {
hostname(args, request) {
return request.hostname;
}
};
const app = express();
app.use(loggingMiddleware);
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(3000, () => console.log('server started'));
In the code above, we created our schema as usual to get the hostname of the app.
Then we added our loggingMiddleware
to log the hostname. It calls next
so we can use our graphqlHTTP
middleware.
Then in our root
resolver, we added a hostname
method, which takes the request
parameter as the second argument, which has the Express request object.
This is where we can return the hostname
property from request
so that we can return it in the response.
This means that we can continue to use middleware to handle authentication as we did with REST APIs.
Popular authentication options for Express include Passport, express-jwt
, and express-session
.
Authentication
We can use jsonwebtoken
in our Express GraphQL server as follows to add authentication via JSON web token.
To do this, we first install jsonwebtoken
by running:
npm i `jsonwebtoken`
Then we can include it in our app and then add it to our Express GraphQL server as follows:
const express = require('express');
const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');
const jwt = require('jsonwebtoken');
const unless = require('express-unless');
const schema = buildSchema(`
type Query {
hostname: String
}
`);
const root = {
hostname(args, request) {
return request.hostname;
}
};
const verifyToken = (req, res, next) => {
jwt.verify(req.headers.authorization, 'secret', (err, decoded) => {
if (err){
return res.send(401);
}
next();
});
}
verifyToken.unless = unless;
const app = express();
app.post('/auth', (req, res) => {
const token = jwt.sign({ foo: 'bar' }, 'secret');
res.send(token);
})
app.use(verifyToken.unless({ path: ['/auth'] }));
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: root,
graphiql: true,
}));
app.listen(3000, () => console.log('server started'));
In the code above, we have the verifyToken
middleware to verify the token that’s issued by our auth
route.
In verifyToken
, we called jwt.verify
to verify the token that we passed into the Authorization
header. If we get an error, then we send a 401 response.
Otherwise, we call next
to proceed to the next middleware our route.
In the auth
route, we issue our authentication token by calling jwt.sign
with whatever content we want as the first argument and the token’s secret in the second argument.
Also, we excluded the verifyToken
middleware from the auth
route by using the express-unless
middleware.
We did that by assigning unless
to verifyToken.unless
.
Then now when we want to make a request to our GraphQL server via the /graphql
route, we have to pass in our auth token to the Authorization
header.
This keeps our GraphQL requests more secure. However, we should have an encrypted secret if we’re going to JSON web tokens in the real world.
Conclusion
We can use Express middleware for logging, authentication, or whatever we need them for.
To include middleware, we just call the app.use
method as usual.
We can exclude routes from using the middleware with the express-unless
package.
To add authentication via JSON web tokens, we can use the jsonwebtoken
package to add token issuing and verification capabilities to our Express GraphQL server.
The post Authentication and Express Middleware with GraphQL appeared first on The Web Dev.