Skip to main content

Command Palette

Search for a command to run...

REST APIs Through Rugby Systems Thinking

Updated
6 min read
REST APIs Through Rugby Systems Thinking
L
IT professional with 8+ years of experience supporting and maintaining systems across local and distributed environments, including global user support. Focused on backend systems, Linux administration, DevOps, automation, and secure infrastructure design. I learn through hands-on system building, troubleshooting, and operational analysis, with an emphasis on reliability, observability, and production-ready engineering.

In South African rugby, coordination only works because every participant operates within defined rules. Cheslin Kolbe finishing a counter-attack, Damian Willemse shifting between positions, or Kurt-Lee Arendse exploiting space all depend on shared structure: set phases, agreed signals, and predictable outcomes.

REST APIs operate on the same principle. Systems interact reliably because the rules of communication are strict and well-defined. Once those rules are understood, the system stops looking chaotic.


What is a REST API?

An API (Application Programming Interface) is a formal contract between systems.

It defines:

  • How requests must be structured

  • What responses will look like

  • What operations are permitted

If the request follows the contract, the system responds predictably. If it doesn’t, the request fails early.

This is about a stable interface exposed to consumers.


REST as an Architectural Style

REST (Representational State Transfer) is a set of constraints for designing APIs over HTTP.

It standardises interaction around:

  • Resources (things you operate on)

  • Uniform operations (HTTP methods)

  • Stateless communication

Because it uses HTTP, it inherits a widely understood transport mechanism already used by browsers and networks.


API Types (Access Model, Not Behaviour)

APIs are also classified by who can access them:

  • Public APIs – open to external consumers with documentation and keys

  • Private APIs – internal system-to-system communication

  • Partner APIs – restricted access for approved external organisations

This classification is about governance and not technical design.


Resources, URIs, and URLs

REST models everything as a resource: a player, a match, or a tournament.

URI (Uniform Resource Identifier)

A URI identifies a resource.

Example:

player/911
It is an identifier only. It doesn't define access.

A URI identifies something but doesn’t tell you where or how to access it.

URL (Uniform Resource Locator)

A URL identifies and locates the resource over a network.

Example:

https://tech-journeys.com/players/kolbe This URL identifies Cheslin Kolbe and also tells your system to fetch his data via HTTPS from this exact location.

All URLs are URIs because they identify a resource, but not all URIs are URLs.

Quick Rule of Thumb

  1. URI: identifies a resource (who/what)

  2. URL: identifies a resource and tells you how to locate it (who/what + where/how)

  3. Relationship: Every URL is a URI, but not every URI is a URL.

Rugby Analogy Summary

Here’s an example written in Python:

# Define a list of players (unique identifiers in the system)
player_uris = [
    "players/kolbe",
    "players/smith",
    "players/duplessis",
    "players/mapimpi"
]

# Base URL of our rugby API or website
base_url = "https://tech-journeys.com/"

# Loop through each player and generate their full URL
for uri in player_uris:
    player_url = f"{base_url}{uri}"
    print("Player URI:", uri)
    print("Player URL:", player_url)
    print("-" * 40)  # separator for readability

Output


HTTP Methods as System Operations

REST defines standard actions via HTTP methods.

GET – Read State

A GET request asks the server for information without changing anything.

import requests

# Get Cheslin Kolbe's stats
response = requests.get("https://tech-journeys.com/players/kolbe") #This URL doesn't really exist :)
player_data = response.json()
print(player_data)

Output

{
  "name": "Cheslin Kolbe",
  "team": "South Africa",
  "position": "Wing",
  "special_move": "Ankle Breaker",
  "world_cups": [2019, 2023]
}

POST – Create Resource

A POST request sends new information to the server to create something that does not yet exist like adding a new player to the squad.

new_player = {
    "name": "Canan Moodie",
    "team": "South Africa",
    "position": "Centre",
    "world_cups": [2023]
}

response = requests.post("https://tech-journeys.com/players", json=new_player)
print(response.status_code)  # 201 means created

PUT – Updating Resource

A PUT request replaces or updates an existing resource. For example, updating a player’s position after a tactical change.

updated_position = {
    "position": "Fullback"
}

response = requests.put("https://tech-journeys.com/players/kolbe", json=updated_position)
print(response.status_code)  # 200 means success

DELETE — Remove Resource

A DELETE request removes a resource completely.

response = requests.delete("https://tech-journeys.com/players/retired_player_id")
print(response.status_code)  # 204 means no content, successfully deleted

A Simple System Design View

A REST system typically follows a simple flow:

Client → API Server → Database
  • Client: browser, mobile app, or script

  • API Server: request validation, routing, business logic

  • Database: persistent storage of resources

The API server enforces rules and isolates clients from internal complexity.


Data Format: JSON

APIs exchange data using JSON (JavaScript Object Notation).

Example of a player in JSON:

{
  "name": "Cheslin Kolbe",
  "team": "South Africa",
  "position": "Wing",
  "special_move": "Ankle Breaker",
  "world_cups": [2019, 2023]
}

It is structured as key-value pairs and arrays, optimised for machine parsing and human readability.


Security Model

APIs expose controlled entry points to systems. Without controls, they become attack surfaces.

Authentication (Identity)

Confirms who is making the request.

Example:

import requests

headers = {"Authorization": "Bearer YOUR_JWT_TOKEN"}
response = requests.get("https://tech-journeys.com/players/kolbe", headers=headers)
print(response.json())

Common mechanisms:

  • API keys

  • JWT (JSON Web Tokens)


Authorisation (Permissions)

Determines what the authenticated identity is allowed to do. Identity alone is insufficient.


Encryption (Transport Security)

HTTPS enforces TLS encryption between client and server. This prevents interception or tampering in transit.


Rate Limiting (Abuse Control)

APIs enforce request thresholds (e.g., 100 requests/minute) to protect infrastructure from overload and denial-of-service patterns.


Core Mental Model

REST becomes simpler when reduced to state transitions:

  • GET → observe state

  • POST → create state

  • PUT → modify state

  • DELETE → remove state

Everything else is implementation detail around those transitions.


My approach to complex systems

Over time, I’ve learned that most systems only feel complex until you relate them to something familiar. Once you do that, the moving parts become easier to reason about.

A GET request is just observing state.
A POST request is introducing change.
Access control is no different from checking permissions at a gate.

The specific analogy doesn’t matter. It could be rugby, football, baking, or fixing cars. What matters is mapping abstract behaviour to something you already understand.

That shift in thinking turns technical concepts into something more durable. Instead of memorising terminology, you recognise patterns. And once you recognise the pattern, it’s much easier to apply it when you’re building or debugging real systems.

More from this blog

T

Tech-Journey

24 posts

Hands-on exploration of Linux, backend systems, system design, and DevOps with a focus on building transferable, production-ready engineering skills through real system behaviour, troubleshooting, and experimentation.