NT
NiyajTech
Get Free Quote

Response within 24 hours · No commitment

#13Architecture· 8 min read13reads

API Architectures Explained: REST vs. GraphQL vs. gRPC

When building modern applications, choosing the right way for different services to communicate is crucial. Let's break down REST, GraphQL, and gRPC with examples.

🎯 REST API🎯 GraphQL vs REST🎯 gRPC tutorial🎯 API architecture🎯 Node.js API examples

When building modern applications, choosing the right way for different services to communicate is crucial. Three of the most common architectures are REST, GraphQL, and gRPC. Let's break down what they are, how they work, and look at some simple examples.

1. REST (Representational State Transfer)

REST is the traditional, widely adopted standard for web APIs. It treats data as "resources," which are accessed via standard URLs. It relies heavily on standard HTTP methods to perform actions on these resources.

  • How it works: You make an HTTP request to a specific endpoint (URL), and the server responds with the data, typically in JSON format.
  • Key Characteristics:
    • Resource-based: Everything is a resource (e.g., /users, /products).
    • Stateless: Each request contains all the information needed by the server to fulfill it.
    • Standard HTTP Methods: Uses GET (read), POST (create), PUT/PATCH (update), and DELETE (remove).

Best for: Standard web applications, public-facing APIs, and when you need strict caching or standard HTTP tooling.

REST Example (Node.js/Express)

const express = require('express');
const app = express();

// A simple mock database
const users = [
  { id: 1, name: 'Alice', role: 'Admin' },
  { id: 2, name: 'Bob', role: 'User' }
];

// GET: Fetch all users
app.get('/api/users', (req, res) => {
  res.json(users);
});

// GET: Fetch a specific user
app.get('/api/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).send('User not found');
  res.json(user);
});

app.listen(3000, () => console.log('REST API running on port 3000'));

2. GraphQL

Developed by Facebook, GraphQL is a query language for your API. Instead of having multiple endpoints returning fixed data structures (like REST), GraphQL has a single endpoint that allows the client to ask for exactly what it needs, nothing more, nothing less.

  • How it works: The client sends a "query" detailing the specific fields it wants. The server processes the query and returns a JSON response matching that exact structure.
  • Key Characteristics:
    • Client-driven: Solves the problems of over-fetching (getting too much data) and under-fetching (needing multiple requests to get all the data).
    • Strongly Typed: Relies on a predefined schema that dictates what data can be requested.
    • Single Endpoint: Usually operates over a single /graphql URL, typically using POST.

Best for: Mobile applications (to save bandwidth), complex UIs requiring data from multiple sources, and when frontend teams need flexibility without waiting for backend changes.

GraphQL Example (Node.js/Apollo Server)

const { ApolloServer, gql } = require('apollo-server');

// 1. Define the Schema
const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    role: String
  }

  type Query {
    users: [User]
    user(id: ID!): User
  }
`;

// 2. Define the Data
const usersData = [
  { id: '1', name: 'Alice', role: 'Admin' },
  { id: '2', name: 'Bob', role: 'User' }
];

// 3. Define Resolvers (How to fetch the data)
const resolvers = {
  Query: {
    users: () => usersData,
    user: (parent, args) => usersData.find(u => u.id === args.id),
  },
};

// 4. Start the Server
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
  console.log(`GraphQL Server ready at ${url}`);
});

Client Query Example to fetch just the names:

query {
  users {
    name
  }
}

3. gRPC (gRPC Remote Procedure Calls)

Developed by Google, gRPC is a modern, high-performance framework that evolves the old RPC (Remote Procedure Call) concept. It's designed to make a function call on a remote server look exactly like a local function call.

  • How it works: You define your service and message structures using Protocol Buffers (Protobuf). The gRPC tooling then generates the client and server code for you in almost any language.
  • Key Characteristics:
    • Protocol Buffers: Uses Protobuf instead of JSON. Protobuf is a binary format, making it much smaller and faster to serialize/deserialize.
    • HTTP/2: Built on HTTP/2, allowing for multiplexing, streaming (client, server, or bidirectional), and reduced latency.
    • Action-oriented: Focuses on calling specific functions or methods rather than acting on resources.

Best for: Microservices communication (internal traffic), low-latency systems, polyglot environments (where services are written in different languages), and streaming data.

gRPC Example (Node.js)

First, you define the service in a .proto file.

user_service.proto

syntax = "proto3";

// The request message containing the user's ID.
message UserRequest {
  int32 id = 1;
}

// The response message containing the user's details.
message UserResponse {
  int32 id = 1;
  string name = 2;
  string role = 3;
}

// The service definition.
service UserService {
  rpc GetUser (UserRequest) returns (UserResponse) {}
}

gRPC Server (Node.js)

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

// Load the protobuf
const packageDefinition = protoLoader.loadSync('user_service.proto', {});
const userProto = grpc.loadPackageDefinition(packageDefinition);

const usersData = [
  { id: 1, name: 'Alice', role: 'Admin' },
  { id: 2, name: 'Bob', role: 'User' }
];

// Implement the GetUser method
function getUser(call, callback) {
  const user = usersData.find(u => u.id === call.request.id);
  if (user) {
    callback(null, user); // Send the user back
  } else {
    callback({
      code: grpc.status.NOT_FOUND,
      details: "Not found"
    });
  }
}

// Start the server
const server = new grpc.Server();
server.addService(userProto.UserService.service, { getUser: getUser });
server.bindAsync('127.0.0.1:50051', grpc.ServerCredentials.createInsecure(), () => {
  console.log('gRPC Server running at http://127.0.0.1:50051');
  server.start();
});

Summary Comparison

Feature REST GraphQL gRPC
Model Resource-based (URLs) Query-based (Single Endpoint) Action-based (Function calls)
Data Format Usually JSON JSON Protocol Buffers (Binary)
Transport HTTP/1.1 (usually) HTTP/1.1 (usually) HTTP/2
Primary Use Case Public APIs, Standard Web Mobile, Complex UIs, Flexible data needs Internal Microservices, High Performance
Learning Curve Low Medium High

NiyajTech

Ready to Start Your Project?

Get a free quote from our Haryana-based IT team. We respond within 24 hours with a clear plan and pricing.

Get a Free Quote →
← All Blog Posts