Skip to content

Note Of RESTful (With Python FastAPI + CURL Example)

Last Updated on 2024-06-02 by Clay

Introduction

RESTful design (Representational State Transfer, REST) is an architectural style for designing network applications. It follows principles that make network applications simpler, more scalable, and easier to maintain.

Below are the core concepts and principles of RESTful design:

Core Concepts

  1. Resources:
    • Resources are any entities on the network, such as users, images, documents, etc.
    • Each resource is uniquely identified by a URI (Uniform Resource Identifier).
  2. Representations:
    • Resources can have multiple representations, such as JSON, XML, HTML, etc.
    • Clients interact with resources through these representations.
  3. State Transfer:
    • Interactions between clients and servers are stateless; each request contains all necessary information.
    • State transfer occurs through HTTP methods (e.g., GET, POST, PUT, DELETE).


Basic Principles

  1. Statelessness:
    • Each request should be independent and not rely on previous requests.
    • Servers do not retain client state between requests.
  2. Uniform Interface:
    • Use standard HTTP methods and status codes.
    • Resource representations should be meaningful for clients to understand and use them.
  3. Scalability:
    • Improve scalability through stateless requests and layered system design.
  4. Cacheability:
    • Servers should explicitly indicate which resources are cacheable to improve performance.
  5. Layered System:
    • Clients do not need to know if they are directly communicating with the final server; requests may go through multiple intermediary layers.
    • This layered design helps improve scalability and security.
  6. Code on Demand (Optional):
    • Servers can transfer executable code (e.g., JavaScript) to clients for execution at runtime.


HTTP Methods

When designing APIs based on RESTful principles, it’s important to use the following HTTP request methods:

  1. GET:
    • Used to retrieve resources.
    • This is a read-only operation and does not change the state of the resource.
  2. POST:
    • Used to create new resources.
    • Typically, a new resource is created on the server, and its URI is returned.
  3. PUT:
    • Used to update existing resources.
    • If the resource does not exist, a new one can be created (similar to an upsert operation combining insert and update).
  4. DELETE:
    • Used to delete resources.
  5. PATCH:
    • Used to partially update resources.

By adhering to these principles, we can design APIs that are simple, scalable, maintainable, and flexible. Let’s proceed with a practical example.


Practical Example

Below is a simple RESTful API interface using Python’s FastAPI, covering basic CRUD operations.

from typing import List, Optional

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uvicorn

app = FastAPI()

# Define resource model
class Item(BaseModel):
    id: int
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

# Simulated database
items_db = []

# POST - Create resource
@app.post("/items/", response_model=Item)
def create_item(item: Item):
    for db_item in items_db:
        if db_item.id == item.id:
            raise HTTPException(status_code=400, detail="Item already exists")
    items_db.append(item)
    return item

# GET - Get all resources
@app.get("/items/", response_model=List[Item])
def read_items():
    return items_db

# GET - Get a specific resource
@app.get("/items/{item_id}", response_model=Item)
def read_item(item_id: int):
    for item in items_db:
        if item.id == item_id:
            return item
    raise HTTPException(status_code=404, detail="Item not found")

# PUT - Update resource
@app.put("/items/{item_id}", response_model=Item)
def update_item(item_id: int, updated_item: Item):
    for index, item in enumerate(items_db):
        if item.id == item_id:
            items_db[index] = updated_item
            return updated_item
    raise HTTPException(status_code=404, detail="Item not found")

# PATCH - Partially update resource
@app.patch("/items/{item_id}", response_model=Item)
def partial_update_item(item_id: int, item_update: dict):
    for item in items_db:
        if item.id == item_id:
            if "name" in item_update:
                item.name = item_update["name"]
            if "description" in item_update:
                item.description = item_update["description"]
            if "price" in item_update:
                item.price = item_update["price"]
            if "tax" in item_update:
                item.tax = item_update["tax"]
            return item
    raise HTTPException(status_code=404, detail="Item not found")

# DELETE - Delete resource
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
    for index, item in enumerate(items_db):
        if item.id == item_id:
            del items_db[index]
            return {"detail": "Item deleted"}
    raise HTTPException(status_code=404, detail="Item not found")

if __name__ == "__main__":
    uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)

CURL Terminal Request Examples

After starting the FastAPI service, you can use the following HTTP methods to request resources. Here are the commands; prepend each with the curl command to test.

Create Resource (POST)

-X POST "http://127.0.0.1:8000/items/" -H "Content-Type: application/json" -d '{"id": 1, "name": "Item1", "description": "A sample item", "price": 10.0, "tax": 1.0}'


Get All Resources (GET)

-X GET "http://127.0.0.1:8000/items/"


Get a Single Resource (GET)

-X GET "http://127.0.0.1:8000/items/1"


Update Resource (PUT)

-X PUT "http://127.0.0.1:8000/items/1" -H "Content-Type: application/json" -d '{"id": 1, "name": "Updated Item", "description": "Updated description", "price": 20.0, "tax": 2.0}'


Partially Update Resource (PATCH)

-X PATCH "http://127.0.0.1:8000/items/1" -H "Content-Type: application/json" -d '{"name": "Partially Updated Item", "price": 15.0}'


Delete Resource (DELETE)

-X DELETE "http://127.0.0.1:8000/items/1"



These commands display how to use curl to request the RESTful APIs.


References


Read More

Leave a Reply