Every API begins with a question: what problem does this solve? Before writing a single line of code, you need to understand your consumers, your data model, and your constraints.

The API Contract

An API is a contract between your service and its consumers. Like any good contract, it should be:

  • Clear — endpoints should be self-documenting
  • Consistent — patterns should repeat predictably
  • Stable — changes should never break existing consumers

Your First Endpoint

Let’s start with a simple resource. Here’s a basic articles API in Ruby:

class ArticlesController < ApplicationController
  def index
    articles = Article.published.recent
    render json: articles, status: :ok
  end

  def show
    article = Article.find(params[:id])
    render json: article, status: :ok
  rescue ActiveRecord::RecordNotFound
    render json: { error: "Article not found" }, status: :not_found
  end
end

Notice the pattern: resource-oriented, HTTP-status-aware, and error-handling built in from the start.

Key Principles

  1. Resources, not actions — Think /articles, not /getArticles
  2. HTTP verbs matter — GET reads, POST creates, PUT/PATCH updates, DELETE removes
  3. Status codes are communication — 200, 201, 404, 422 each tell a different story

The best APIs feel like they were inevitable — as if no other design could have existed.

In the next chapter, we’ll dive into the design principles that make this possible.