Courses Developer Fundamentals for Builders Building with Fetch and REST APIs

JavaScript, APIs, and the Frontend

Building with Fetch and REST APIs

REST principles, Laravel API routes, and the fetch() API

14 min read · Lesson 17 of 18

APIs Connect Everything

REST APIs are the standard way your frontend JavaScript communicates with your Laravel backend, and how external services communicate with your app. Understanding both sides — building and consuming APIs — is essential.


REST Principles

REST (Representational State Transfer) uses HTTP methods and URLs to model resources:

  • GET /api/posts — List all posts
  • GET /api/posts/1 — Get post #1
  • POST /api/posts — Create a new post
  • PUT /api/posts/1 — Replace post #1 entirely
  • PATCH /api/posts/1 — Update specific fields on post #1
  • DELETE /api/posts/1 — Delete post #1

Key principles: resources are nouns (not verbs), use HTTP methods for actions, return appropriate status codes, and use JSON for request/response bodies.


Laravel API Routes

Laravel's routes/api.php file automatically prefixes routes with /api and applies the API middleware (rate limiting, no session):

Route::apiResource('posts', PostApiController::class);
// Creates GET, POST, PUT/PATCH, DELETE routes automatically

Return JSON responses from controllers:

public function index()
{
    return Post::published()->paginate(20);
    // Laravel auto-converts to JSON with pagination metadata
}

public function store(Request $request)
{
    $validated = $request->validate([...]);
    $post = Post::create($validated);

    return response()->json($post, 201); // 201 = Created
}

The Fetch API

JavaScript's fetch() is the modern way to make HTTP requests:

// GET request
const response = await fetch('/api/posts');
const posts = await response.json();

// POST request
const response = await fetch('/api/posts', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
    },
    body: JSON.stringify({
        title: 'New Post',
        body: 'Content here...',
    }),
});

if (!response.ok) {
    const errors = await response.json();
    console.error(errors); // Laravel validation errors
}

Important: fetch() does NOT throw on HTTP errors (404, 500). It only throws on network failures. Always check response.ok or response.status.


Error Handling

Laravel returns structured JSON errors for API requests:

  • 422 (validation) — { "message": "...", "errors": { "title": ["required"] } }
  • 404{ "message": "Not found" }
  • 429 (throttled) — { "message": "Too Many Attempts." }
  • 500{ "message": "Server Error" } (no details in production)

Key Takeaways

  • REST uses HTTP methods + resource URLs as its interface. Keep URLs as nouns, methods as verbs.
  • Laravel's apiResource generates standard CRUD routes. Return JSON with appropriate status codes.
  • fetch() doesn't throw on HTTP errors — always check response.ok.
  • Include CSRF tokens for same-origin requests. Use Bearer tokens for external API clients.
Ask about this lesson