Skip to main content
Which UI do you use?
Custom UI
Pre built UI

Backend Setup

important

This guide uses express, if you are using another backend framework you can use this guide as a reference for the various steps involved in integrating with SuperTokens but some parts may need tweaking depending on the framework you are using.

a) Complete the setup guides#

Follow the frontend and backend pre-built UI setup guides to setup SuperTokens.

b) Install GraphQL dependencies on your backend#

info

We use Apollo server in this example, SuperTokens can be used with other GraphQL libraries as well.

npm install @apollo/server graphql

c) Setup GraphQL#

Create your schema#

In this example we will create a simple social app that allows logged in users to create and view posts. To build an app like this you would need the following:

  • A way for users to login and logout
  • A way for users to create posts
  • A way for users to like posts

For sake of simplicity we will just focus on login/logout and viewing posts.

From a GraphQL perspective we will need the following:

  • A query to fetch the user's posts
const typeDefs = `
type Query {
posts: [String],
}
`;

The posts Query will return a list of String (one for each post) if the user is logged in.

important

We do not add any queries or mutations for login and logout because the SuperTokens middleware exposes APIs that handle this for us.

Refer to the backend pre-built UI setup guides if you have not already added the SuperTokens middleware.

Create resolvers#

We use the Session recipe from supertokens-node to verify that the user is logged in with the getSession function

import Session from "supertokens-node/recipe/session";

const resolvers = {
Query: {
posts: async (_: any, __: any, contextValue: any) => {
// getSession will throw an error if the session does not already exist
let session = await Session.getSession(contextValue.req, contextValue.res);
let userId = session.getUserId();
// TODO: Fetch all posts for the user using the userId
return [];
}
},
}
note

In the code above we read req and res from contextValue, refer to the next step to see how this is being added to the graphql context

Refer to the official Apollo guide to know more about creating queries, mutations and resolvers.

d) Add the Apollo middleware and SuperTokens error handler to your server#

Setting up Apollo server#

Now that we have our schema setup, we need to create an instance of the Apollo server.

The SuperTokens SDK can throw errors (for example if the user is not logged in) which need to handled in a specific way. By default Apollo handles all errors by returning a HTTP status 200 and the description of the error, which is not supported by the SuperTokens frontend SDKs.

To work around this we create a custom plugin for the Apollo server that will handle errors thrown by the SuperTokens SDK, all other errors will be handled as they normally would by Apollo. The errorHandler exposed by the SuperTokens backend SDK will identify if an error is thrown by the SDK itself and handle it accordingly.

import { ApolloServer } from "@apollo/server";
import express from "express";
import {errorHandler} from "supertokens-node/framework/express/index.js";

let app = express();

const typeDefs = '' // TODO: Refer to previous step
const resolvers = {} // TODO: Refer to previous step

const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [
{
requestDidStart: async () => {
return {
didEncounterErrors: async (requestContext) => {
const {req, res} = requestContext.contextValue as any;
for (let i = 0; i < requestContext.errors.length; i++) {
let error = requestContext.errors[i].originalError;
await new Promise(async (resolve) => {
// This will handle any session or other SuperTokens related errors
await errorHandler()(error, req, res, (err) => {
resolve(undefined);
});
});
}
},
};
}
}
],
})

Adding the Apollo middleware#

info

When using Apollo server, you must use expressMiddleware in order to use SuperTokens because startStandaloneServer does not let you configure custom CORS settings

import { ApolloServer } from "@apollo/server";
import express from "express";
import { expressMiddleware } from "@apollo/server/express4";
import {errorHandler} from "supertokens-node/framework/express/index.js";

let app = express();

const typeDefs = '' // TODO: Refer to previous step
const resolvers = {} // TODO: Refer to previous step

const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [
// TODO: Refer to the previous section
],
})

server.start().then(() => {
// Use expressMiddleware only after server.start has resolved
app.use(express.json(), expressMiddleware(server, {
context: async ({req, res}) => {
return {
// We add this so that we can access sessions in the resolvers
req,
res,
};
},
}))

app.listen(3001, () => {
console.log("Server started");
})
})
important

We add the request and response objects to the GraphQL context object when using expressMiddleware. These are then used in the resolvers in the previous steps along with the Session recipe for supertokens-node.

Refer to this page to know more about the session object