Bird
Raised Fist0
Expressframework~5 mins

REST vs GraphQL awareness in Express

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction

REST and GraphQL are two ways to get data from a server. They help your app talk to the backend and show information to users.

You want to build a simple app that gets data from a server with fixed endpoints.
You need to let users ask for exactly the data they want to reduce extra information.
You want to support many different clients like web, mobile, or smart devices with one API.
You want to easily add or change data fields without breaking old clients.
You want to control how much data is sent to save bandwidth and speed up loading.
Syntax
Express
/* REST example: Express GET endpoint */
app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  // fetch user by userId
  res.json(userData);
});

/* GraphQL example: Single endpoint with query */
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
const schema = buildSchema(`
  type Query {
    user(id: ID!): User
  }
  type User {
    id: ID
    name: String
    email: String
  }
`);

const root = {
  user: ({ id }) => {
    // fetch user by id
  }
};

app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));

REST uses multiple URLs for different data types and actions.

GraphQL uses one URL and lets clients specify what data they want in a query.

Examples
REST uses different URLs for different requests.
Express
/* REST: Get user by ID */
GET /users/123

/* REST: Get all users */
GET /users
GraphQL lets you ask for specific fields in one request.
Express
/* GraphQL: Query user by ID */
{
  user(id: "123") {
    id
    name
  }
}
REST uses HTTP methods like PUT to update data.
Express
/* REST: Update user email */
PUT /users/123
{
  "email": "new@example.com"
}
GraphQL uses mutations to change data with flexible responses.
Express
/* GraphQL: Mutation to update user email */
mutation {
  updateUser(id: "123", email: "new@example.com") {
    id
    email
  }
}
Sample Program

This program shows both REST and GraphQL ways to get user data by ID. You can try REST by visiting /users/1 or GraphQL by sending a query to /graphql.

Express
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');

const app = express();
app.use(express.json());

// Sample data
const users = [
  { id: '1', name: 'Alice', email: 'alice@example.com' },
  { id: '2', name: 'Bob', email: 'bob@example.com' }
];

// REST endpoint to get user by ID
app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  const user = users.find(u => u.id === userId);
  if (user) {
    res.json(user);
  } else {
    res.status(404).json({ error: 'User not found' });
  }
});

// GraphQL schema
const schema = buildSchema(`
  type User {
    id: ID
    name: String
    email: String
  }
  type Query {
    user(id: ID!): User
  }
`);

// Root resolver
const root = {
  user: ({ id }) => users.find(u => u.id === id)
};

// GraphQL endpoint
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true
}));

// Start server
app.listen(4000, () => {
  console.log('Server running on http://localhost:4000');
  console.log('Try REST: GET http://localhost:4000/users/1');
  console.log('Try GraphQL: http://localhost:4000/graphql');
});
OutputSuccess
Important Notes

REST is simple and works well for fixed data needs but can send extra data you don't want.

GraphQL lets clients ask for exactly what they need, reducing data transfer.

GraphQL requires learning query language and setting up a schema, which can be more complex.

Summary

REST uses multiple URLs and HTTP methods to get and change data.

GraphQL uses one URL and lets clients specify exactly what data they want.

Choose REST for simple APIs and GraphQL for flexible, efficient data fetching.

Practice

(1/5)
1. Which statement best describes the main difference between REST and GraphQL in an Express API?
easy
A. REST uses multiple URLs and HTTP methods; GraphQL uses a single URL with flexible queries.
B. REST uses a single URL and flexible queries; GraphQL uses multiple URLs and HTTP methods.
C. REST and GraphQL both use multiple URLs but differ in data format.
D. REST and GraphQL are identical in how they handle data fetching.

Solution

  1. Step 1: Understand REST API structure

    REST APIs use different URLs (endpoints) for different resources and HTTP methods like GET, POST, PUT, DELETE to perform actions.
  2. Step 2: Understand GraphQL API structure

    GraphQL uses a single endpoint URL and clients specify exactly what data they want in the query, making it flexible.
  3. Final Answer:

    REST uses multiple URLs and HTTP methods; GraphQL uses a single URL with flexible queries. -> Option A
  4. Quick Check:

    REST vs GraphQL = multiple URLs vs single URL [OK]
Hint: REST = many URLs; GraphQL = one URL with queries [OK]
Common Mistakes:
  • Thinking GraphQL uses multiple URLs like REST
  • Confusing HTTP methods usage between REST and GraphQL
  • Believing REST and GraphQL are the same
2. Which Express route setup correctly represents a REST API endpoint for getting a user by ID?
easy
A. app.put('/user', (req, res) => { /* fetch user */ });
B. app.post('/user/:id', (req, res) => { /* fetch user */ });
C. app.get('/user/:id', (req, res) => { /* fetch user */ });
D. app.get('/graphql', (req, res) => { /* fetch user */ });

Solution

  1. Step 1: Identify correct HTTP method for fetching data

    GET method is used to retrieve data in REST APIs.
  2. Step 2: Check URL pattern for resource identification

    /user/:id correctly uses a URL parameter to specify which user to fetch.
  3. Final Answer:

    app.get('/user/:id', (req, res) => { /* fetch user */ }); -> Option C
  4. Quick Check:

    GET + /user/:id = fetch user [OK]
Hint: GET method + URL with :id fetches resource [OK]
Common Mistakes:
  • Using POST instead of GET for fetching data
  • Using GraphQL endpoint for REST question
  • Using PUT method which is for updates
3. Given this Express GraphQL setup, what will the client receive when querying for { user(id: "1") { name } }?
const { graphqlHTTP } = require('express-graphql');
const schema = buildSchema(`
  type Query {
    user(id: ID!): User
  }
  type User {
    id: ID
    name: String
    email: String
  }
`);
const root = {
  user: ({ id }) => ({ id, name: 'Alice', email: 'alice@example.com' })
};
app.use('/graphql', graphqlHTTP({ schema, rootValue: root, graphiql: true }));
medium
A. {"data":{"user":{"id":"1","name":"Alice","email":"alice@example.com"}}}
B. {"data":{"user":{"name":"Alice"}}}
C. {"error":"Field 'user' not found"}
D. {"data":{"user":null}}

Solution

  1. Step 1: Understand the GraphQL query

    The query requests only the name field of the user with id "1".
  2. Step 2: Check resolver returns full user object

    The resolver returns id, name, and email, but GraphQL returns only requested fields.
  3. Final Answer:

    {"data":{"user":{"name":"Alice"}}} -> Option B
  4. Quick Check:

    GraphQL returns only requested fields [OK]
Hint: GraphQL returns only requested fields, not full object [OK]
Common Mistakes:
  • Expecting all fields returned regardless of query
  • Confusing error responses with valid data
  • Assuming REST style full object return
4. Identify the error in this Express REST route that causes it to always return an empty response:
app.get('/users/:id', (req, res) => {
  const user = users.find(u => u.id === req.params.id);
  if (user) {
    res.json(user);
  }
  res.end();
});
medium
A. The route path should be '/user/:id' not '/users/:id'.
B. The route should use POST instead of GET.
C. The user lookup uses incorrect comparison operator.
D. res.end() is called even after sending a response, causing empty output.

Solution

  1. Step 1: Analyze response flow

    If user is found, res.json(user) sends response, but code continues to res.end() which sends empty response again.
  2. Step 2: Understand Express response behavior

    Calling res.end() after res.json() can cause the response to be overwritten or cause errors.
  3. Final Answer:

    res.end() is called even after sending a response, causing empty output. -> Option D
  4. Quick Check:

    Only send one response per request [OK]
Hint: Send only one response; avoid res.end() after res.json() [OK]
Common Mistakes:
  • Using wrong HTTP method for fetching
  • Assuming path name causes empty response
  • Ignoring that res.end() can overwrite response
5. You want to build an Express API that allows clients to fetch user data with flexible fields and avoid multiple endpoints. Which approach is best and why?
hard
A. Use GraphQL with a single endpoint letting clients specify exactly which fields they want.
B. Use REST but return all fields for every resource to avoid multiple endpoints.
C. Use REST with multiple endpoints for each resource and HTTP methods for actions.
D. Use GraphQL but create multiple endpoints for each query type.

Solution

  1. Step 1: Identify requirement for flexible fields and fewer endpoints

    Clients want to specify fields and avoid many URLs.
  2. Step 2: Match approach to requirement

    GraphQL uses one endpoint and allows clients to request exactly needed fields, fitting the requirement.
  3. Final Answer:

    Use GraphQL with a single endpoint letting clients specify exactly which fields they want. -> Option A
  4. Quick Check:

    Flexible fields + single endpoint = GraphQL [OK]
Hint: Flexible data + one URL = GraphQL [OK]
Common Mistakes:
  • Choosing REST and returning all fields wastes bandwidth
  • Using GraphQL with multiple endpoints defeats its purpose
  • Confusing REST flexibility with GraphQL's query power