ThisCalculator

Everyday

Scaffold a GraphQL Server with Node.js

Updated · Standard formula, shown below

Scaffold a GraphQL Server with Node.js

Scaffolding a GraphQL server with Node.js gives you a small, runnable API that accepts GraphQL queries and returns data through a single endpoint. You’ll create a project, define a schema and resolvers, start the server, and test it locally; you’ll need Node.js and npm installed first.

What You’ll Need

  • Node.js, preferably a currently supported LTS release, and npm (npm is included with Node.js).
  • A terminal and a code editor.
  • Basic familiarity with JavaScript, objects, and running commands in a project directory.

Step-by-Step

  1. Create a project directory. Open a terminal and run:
    mkdir graphql-node-server
    cd graphql-node-server
    Initialize the project manifest with npm init -y. This creates a package.json where npm records project details and dependencies.
  2. Install the server packages. For a straightforward server using Apollo Server and Express, install Apollo Server’s Express integration and GraphQL:
    npm install @apollo/server @as-integrations/express5 express graphql
    This setup uses Express 5. If your project specifically needs Express 4, use the matching integration package, @as-integrations/express4, instead. Keep the integration version and Express major version compatible.
  3. Choose how Node.js will run your files. This guide uses ES modules. Add "type": "module" and a start script to package.json. For example, retain the existing fields and ensure the file includes:
    "type": "module",
    "scripts": { "start": "node index.js" }
    JSON does not allow comments or trailing commas. Alternatively, use CommonJS consistently, but do not mix require and import without configuring the project for both.
  4. Create the schema and resolver. In the project directory, create index.js and add:
    import express from 'express';
    import { ApolloServer } from '@apollo/server';
    import { expressMiddleware } from '@as-integrations/express5';
    import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
    import http from 'node:http';

    Then define the API’s shape and the function that supplies its data:
    const typeDefs = `#graphql
    type Query {
    hello: String!
    }
    `;
    const resolvers = {
    Query: {
    hello: () => 'Hello from GraphQL!'
    }
    };
    const app = express();
    const httpServer = http.createServer(app);
    const server = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
    });
    await server.start();
    app.use('/graphql', express.json(), expressMiddleware(server));
    const port = Number(process.env.PORT) || 4000;
    await new Promise((resolve) => httpServer.listen({ port }, resolve));
    console.log(`GraphQL server ready at http://localhost:${port}/graphql`);
    The schema declares a non-null string field. The resolver returns the value for that field. The HTTP server and drain plugin also give the application a clean shutdown path.

  5. Start the server. Save the file and run npm start. If startup succeeds, the terminal prints the local GraphQL endpoint. Leave this process running while you test. Press Ctrl+C to stop it when you are done.
  6. Send a test query. Use an API client that can send a POST request, or run this command in another terminal:
    curl -X POST http://localhost:4000/graphql -H 'content-type: application/json' --data '{"query":"{ hello }"}'
    A successful response contains "data":{"hello":"Hello from GraphQL!"}. GraphQL clients may offer an interactive query editor, but the POST request is enough to confirm the endpoint works.
  7. Add fields deliberately. To return structured data, define a type in typeDefs, add a field that returns it, and implement a resolver with the same type and field names. For example, a Book type might have title: String!. A field marked with ! must not resolve to null; make your resolver and data satisfy that promise.

Common Mistakes

  • Schema and resolver names do not match: Query.hello must match the hello field in the schema, including capitalization.
  • Module settings are inconsistent: If import produces a module error, check "type": "module" or use a consistent CommonJS setup.
  • Package versions are incompatible: Use the Express integration intended for your installed Express major version. Check the npm error and installed packages rather than randomly downgrading dependencies.
  • Request middleware is missing: With Express, express.json() must be applied before Apollo’s Express middleware so JSON request bodies can be parsed.
  • A field returns null unexpectedly: A resolver may be missing, return no value, or fail. A non-null field can cause GraphQL to report an error and null out a parent result.
  • The endpoint is confused with a web page: The GraphQL endpoint is designed for GraphQL requests, typically POST requests; entering its URL in a browser address bar may not display a usable interface.

Tips

  • Keep schema definitions, resolvers, and data-access code separate as the project grows; the single-file example is a starting point, not a required layout.
  • Use variables for values supplied by clients instead of building query strings by concatenating user input.
  • Return predictable errors and validate inputs in resolvers or a dedicated service layer. Do not expose stack traces or internal configuration to clients.
  • Configure secrets and environment-specific settings outside source code. Before making a server public, consider authentication, authorization, input limits, logging, and request-size limits.
  • Use a database only when the application needs persistent data. The initial resolver can return sample data, which makes it easier to verify the GraphQL layer first.

Troubleshooting

“Cannot find package” or module resolution errors: Confirm you are in the project directory, run npm install, and check that the package named in the import exists in package.json. Verify the Express integration matches your installed Express version.

“Address already in use”: Another process may be using port 4000. Stop that process or start the server with another port, for example PORT=4001 npm start on macOS or Linux. In PowerShell, use $env:PORT=4001; npm start.

Connection refused or no response: Make sure the server is still running, use the exact endpoint and port printed in the terminal, and check whether local firewall or proxy settings interfere. The test request must be sent to /graphql.

GraphQL reports an unknown field: Compare the query with the schema. A client can request only fields declared by the schema, and spelling and capitalization must match.

Syntax error on startup: Check index.js for missing braces, quotes, or commas. Check package.json separately: it must be valid JSON and cannot contain comments.

Frequently Asked Questions

What is a GraphQL schema?
It describes the types and fields clients may query, along with the kinds of values those fields return.

What does a resolver do?
A resolver supplies the value for a schema field. It might return a constant, read from a database, or call another service.

Do I need Express to build a GraphQL server with Node.js?
No. GraphQL servers can use different HTTP frameworks or adapters. Express is used here to demonstrate a familiar Node.js setup.

Can I use TypeScript instead of JavaScript?
Yes. Configure a TypeScript compiler or runtime and use compatible package types. The schema and resolver relationship remains the same.

How do I connect a database?
Call your data-access layer from resolvers and return values that match the schema. Keep database connection setup outside individual field resolvers where practical.

Is this server ready for production?
It is a local scaffold, not a complete production configuration. Add appropriate access controls, validation, operational logging, resource limits, and deployment-specific settings before exposing it publicly.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.