Topzee logo
Open menu
Web and AI Integrations

REST API Basics for Beginners: A Mobile Developer's Guide

REST API fundamentals explained specifically for mobile developers who've only ever consumed APIs, not built them.

Topzee4 min read
Abstract REST API basics cover with request and response paths between a phone and backend service.

REST API basics for beginners can feel confusing if you are a mobile developer who has only consumed APIs from Flutter, Swift, or Kotlin. You know how to call an endpoint, but the backend side can still feel like a black box.

Understanding the basics helps you debug faster, ask better questions, and design cleaner mobile integrations.

REST API Basics for Beginners: What REST Is

REST is an architectural style for designing web APIs around resources. A resource is a thing your app cares about: users, tasks, orders, products, messages, or sessions.

Each resource usually has a URL:

/users
/tasks
/orders/123

The HTTP method tells the server what action you want to perform.

HTTP Methods Mobile Developers Use Daily

GET reads data.

GET /tasks

Use it when your mobile app loads a list, profile, dashboard, or detail screen.

POST creates something new.

POST /tasks

Use it when a user submits a new form, creates an account, sends a message, or adds a task.

PUT replaces a resource.

PUT /tasks/123

Use it when the client sends the full updated version of a resource.

PATCH partially updates a resource.

PATCH /tasks/123

Use it when changing one or two fields, such as marking a task complete.

DELETE removes a resource.

DELETE /tasks/123

Use it when the user deletes data.

Status Codes That Matter

You do not need to memorize every HTTP status code. Start with the ones you see often.

200 OK: request succeeded.

201 Created: new resource created successfully.

204 No Content: success, but no response body.

400 Bad Request: client sent invalid input.

401 Unauthorized: user is not authenticated.

403 Forbidden: user is authenticated but not allowed.

404 Not Found: resource does not exist.

409 Conflict: request conflicts with current state.

422 Unprocessable Entity: validation failed.

500 Internal Server Error: server failed unexpectedly.

Mobile apps should translate these into useful UI states. A 401 may navigate to login. A 422 may show form validation. A 500 may show retry copy.

Build a Minimal Express API

Install Express:

npm install express
npm install --save-dev typescript tsx @types/express

Create a small server:

import express from "express";

const app = express();

// This lets Express read JSON request bodies from mobile apps and API clients.
app.use(express.json());

type Task = {
  id: string;
  title: string;
  completed: boolean;
};

// In-memory storage keeps the example simple. A real app would use a database.
const tasks: Task[] = [];

// GET returns the current list of tasks.
app.get("/tasks", (req, res) => {
  res.json(tasks);
});

// POST creates a new task from the JSON body sent by the client.
app.post("/tasks", (req, res) => {
  const title = String(req.body.title ?? "").trim();

  // 422 tells the mobile app the request was understood, but validation failed.
  if (!title) {
    return res.status(422).json({ error: "Title is required" });
  }

  const task: Task = {
    id: crypto.randomUUID(),
    title,
    completed: false,
  };

  tasks.push(task);

  // 201 means a new resource was created successfully.
  return res.status(201).json(task);
});

// PATCH updates one field on an existing task.
app.patch("/tasks/:id", (req, res) => {
  const task = tasks.find((item) => item.id === req.params.id);

  // 404 tells the app this task ID does not exist on the server.
  if (!task) {
    return res.status(404).json({ error: "Task not found" });
  }

  // Only update completed when the client sends a real boolean.
  if (typeof req.body.completed === "boolean") {
    task.completed = req.body.completed;
  }

  return res.json(task);
});

// Start the API locally so you can call it from Postman, curl, or your app.
app.listen(3000, () => {
  console.log("API running on http://localhost:3000");
});

This is not production storage, but it shows the shape: method, route, validation, status code, JSON response.

How This Connects to Flutter

When a Flutter app calls POST /tasks, it should send JSON:

Uri apiEndpoint(String path) {
  // Pass this at build/run time, for example:
  // flutter run --dart-define=API_BASE_URL=http://localhost:3000
  const apiBaseUrl = String.fromEnvironment('API_BASE_URL');

  // Fail early instead of making requests to an empty or invalid URL.
  if (apiBaseUrl.isEmpty) {
    throw StateError('API_BASE_URL is not configured');
  }

  // Build a full endpoint like http://localhost:3000/tasks.
  return Uri.parse(apiBaseUrl).replace(path: path);
}

final response = await client.post(
  apiEndpoint('/tasks'),
  // Tell the server the request body is JSON.
  headers: {'Content-Type': 'application/json'},
  body: jsonEncode({'title': 'Ship blog launch'}),
);

Then it should handle the status code:

if (response.statusCode == 201) {
  // Parse task and update UI.
} else if (response.statusCode == 422) {
  // Show validation message.
} else {
  // Show fallback error.
}

Good backend design makes mobile code simpler. Clear status codes and predictable JSON reduce guesswork in the app.

Practical Advice

If you are a mobile developer learning backend basics, build one tiny API from scratch. Do not start with authentication, payments, deployment, and file uploads. Start with one resource and four routes.

Once that is clear, your API consumption code in Flutter will make more sense.

If your mobile app needs a backend but the API contract is still vague, Beyond Just Digital can help define the endpoints before the frontend and backend drift apart.