Website API Integration Basics: From REST to GraphQL

A content site is rarely "one program": pages need to load article lists, registration needs to submit forms, avatars need to be uploaded, search needs a third-party integration. Every one of those actions is an API call behind the scenes. An API turns that data exchange into a set of rules — the frontend requests according to the rules, and the backend answers accordingly. This article walks from REST to GraphQL to give you a solid foundation for wiring up your site's frontend and backend.

RESTful API Basics

REST (Representational State Transfer) is the most widely used API design style, and most public interfaces — GitHub, Stripe, Alipay's open platform — follow it. Its core idea is to treat every business object as a "resource", located by a URL and acted upon via an HTTP method.

Core principles

  • Resource-oriented URLs (/api/users, /api/articles)
  • HTTP method semantics: GET/read, POST/create, PUT/update, DELETE/delete
  • Stateless: each request carries everything needed to complete it; the server keeps no session
  • Uniform interface: consistent URL structure and response format, no special client conventions

Design example

Taking the article module as an example, a typical REST API is organized like this:

Method Endpoint Description
GET /api/articles List articles (with pagination params)
GET /api/articles/:id Fetch a single article
POST /api/articles Create an article
PUT /api/articles/:id Update an article
DELETE /api/articles/:id Delete an article

Responses are usually JSON with a consistent envelope, such as { "code": 0, "data": [...], "message": "ok" }. Status codes matter too: 200 success, 201 created, 400 bad request, 401 unauthenticated, 404 not found, 429 rate limited, 500 server error. When the frontend gets a non-2xx status, it should branch into error handling rather than blindly parsing the body.

Frontend call example

// Use the Fetch API to call a REST endpoint
async function getArticles() {
  const response = await fetch('/api/articles');
  if (!response.ok) throw new Error('Failed to fetch');
  return response.json();
}

// POST request
async function createArticle(data) {
  const response = await fetch('/api/articles', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  });
  return response.json();
}

Two things are easiest to miss when writing frontend calls. First, error handling: fetch only rejects on network failure — HTTP 4xx/5xx do not throw, so you must check response.ok yourself. Second, request cancellation: when users switch pages quickly, use AbortController to cancel stale requests so an old response does not overwrite the current page state. For a more systematic design guide, see REST API design guide.

GraphQL Basics

GraphQL is a query language created by Facebook. It flips the model from "backend defines endpoints" to "frontend asks for what it needs": the client declares which fields it wants, and the server returns only those. For sites reused across web and mobile, or pages whose field needs differ a lot, it reduces redundant payloads noticeably.

REST vs GraphQL

Aspect REST GraphQL
Data fetching Fixed structure Client-defined
Over-fetching Common Does not happen
Multiple requests Often needed Single request
Learning curve Low Medium
Caching Native HTTP cache Needs extra setup
Tooling ecosystem Mature Growing fast

GraphQL query example

# Query: fetch only the fields you need
query {
  articles(first: 10) {
    id
    title
    author {
      name
    }
  }
}

# Mutation: create data
mutation {
  createArticle(title: "Hello", content: "World") {
    id
    title
  }
}

How to choose: a pragmatic take

For most small and mid-size sites, start with REST, add GraphQL later is the more stable path. The decision rules are simple:

  • Many pages, wildly different field needs, mobile reuse → GraphQL's on-demand fetching pays off more;
  • Small team, simple endpoints, lots of existing REST code → keep REST and avoid the maintenance cost of a schema and resolver layer;
  • When "one page needs five calls to assemble its data" becomes a real pain, then consider GraphQL as an aggregation layer.

Whichever you pick, agree on how the API documentation is maintained: describe REST with OpenAPI/Swagger, and rely on GraphQL's built-in introspection. The documentation is the foundation of frontend/backend collaboration — when it drifts from the implementation, integration eats far too much time.

Version your API (/api/v2/... or an Accept header) so upgrades do not break old clients, and land cross-cutting concerns like auth, rate limiting, and logging via API security and auth. For backend engineering practice, see the backend integration category, such as Node.js API example; for storage choices, see database selection guide.

Frequently asked questions

  • What if the endpoint is slow: check for N+1 queries first, then missing indexes, then consider CDN and database caching.
  • Should I use an SDK: official SDKs bundle auth, retries, and types, but plain fetch is perfectly fine for small projects.
  • How to debug CORS errors: the backend must return the correct Access-Control-Allow-Origin; enable credentials when cookies need to travel with the request.
  • How to separate environments: prepare dev, staging, and prod, and switch baseURL via environment variables so test data never pollutes production endpoints.

Reference: Microsoft's Azure Architecture Center Web API design guidance is at https://learn.microsoft.com/azure/architecture/best-practices/api-design; the official GraphQL specification is at https://graphql.org/learn/.