Wed Apr 08 2026

1. Introduction

source:

In the real world, a certain system or an application provides services to the client. The client and the application may reside in the same local system for them to talk to each other directly. In usual cases, this is not the case; the application and the client reside in separate systems, often far away from each other. In order to communicate with each other and for the application to provide services to the client, the application follows the http channel to establish connection between the two.

HTTP provides an interface for the server and client to communicate with each other. They communicate through messages. Each message is either a request or a response. The client sends a request to the server and the server listens to it and performs the actions intended by the request and send the response back to the client. The core entity on the server side is a resource as far as the client is concerned. The resource is what a target of a request. Each resource is identified by a Uniform Resource Identifier (URI) and has a representation.

It provides the tools like GET, POST, Headers, BODY, etc that allows the client to communicate with the server and vice-versa. For ex, the following string of text communicates to the server using the GET instruction.

GET /user/octocat HTTP/1.1
Host: api.github.com
User-Agent: curl/7.68.0
Accept: */*

The first line follows the syntax [METHOD] [PATH] [HTTP VERSION]. In the server, it is splitted using the spaces and the server takes the action according to the method.

Installation: Install the FastAPI using the following cli pip install fastapi[standard].

There are several tools that allow communicating with the server using the RestAPI.

  • REST Client (VS Code Extension)
  • Thunder Client (VS Code Extension)
  • Postman
  • curl (CLI)
  • Browser

We will use REST Client in this tutorial. Install the extension and create a file .http in the root of project folder. Try writing the line GET https://github.com. The extension will automatically inject a button in the file to send the request. The response from the server will be displayed in a split window. The simple cli command curl https://github.com does the same GET request.

When we write the address in the search bar of a browser, it performs the GET request to the addrfess. To perform complex requests, use developer console and se the fetch() api.

RestAPI consists of several components that together work to convert the client requests to server language and vice-versa.

Client Request: The client request comprises the instruction and data provided by the client tools like browser. It consists of the following.

  • HTTP Method: The actions to be performed. GET, POST, PUT, PUSH, DELETE, etc.
  • Headers: Metadata that contains, for ex, the information about the content type.
  • Payload/Body: The data being sent to the server.

Routing: It routes the requests to specific functions in the code to perform the task intended.

Validation & Deserialization: It checks the data to ensure the request follows the same schema as expected by the server. It also performs the conversion of the content provided by the client to the objects processed by the code in the server.

Logic: The actual functions that provide the service to the client.

Serialization & Response Formatting: It converts back the objects back to the format understood by the client.

2. A Simple FastAPI Application

Create a file main.py. This file is an entry point for the FastAPI.

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root()
    return {"message": "Hello Client!"}

The file defines the endpoint GET which when requested would return the message distionary.

Launching FastAPI Server: The fastapi server can be started by running the cli command fastapi dev in the fastapi root folder where the main.py file sits. Alternatively, if the api is a part of another project, in the pyproject.toml file, the following line tells the fastapi to where to look at the main file.

[tool.fastapi]
entrypoint = "path.to.main:app"

Now, the fastapi server can be launched directly from the root of the main project. Run the command to spin up the server and go the url mentioned in

INFO Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

The browser will display the message returned by the function root(). Or, one can run the command in another terminal window curl http://127.0.0.1:8000.

The path specified in @app.get("/") specifies the endpoint where the GET request will be triggered. In this case it is the exact url where the server is hosted. Alternatively, we can append another path to the main path to create custom paths for the resources.

2.1 Method Binding

The HTTP cmes with a set of methods to perform action on the resources. Each of those methods are binded to specific functions that perform the action using decorators provided by the FastAPI.

  • GET -> @app.get("/path/to/resource")
  • POST -> @app.post("/path/to/resource")
  • DELETE -> @app.delete("/path/to/resource")
  • PUT -> @app.put("/path/to/resource")

2.2 Path Parameters and Queries

The path to the resources can contain parameters. The parameters will be passed to the function binded to the corresponding method acting on the resource. For ex, in the previous case, we can add a paramter id to the path.

@app.get("/{id}")
def root(id):
    return {"id": id}

The extra parameters required by the methods are designated as query parameters. These parameters need to be passed to the server by appending to the resource URI. The below program takes the starting and end indices to fetch a range of rows from a pandas dataframe.

from fastapi import FastAPI
from pandas import read_parquet

app = FastAPI()

@app.get("/db/")
def get(end_ix: int, start_ix: int=0):
    filepath = "path/to/file.parquet"
    db = read_parquet(filepath)

    return {"message": f"Hello client! Here is the rows from the database {filepath} from row {start_ix} to {end_ix}",
            "content": db[start_ix:end_ix]}

Using the request

curl http:/mainpath/db/?end_ix=3

{“message”:“Hello client! Here is the rows from the database data/cat_facts.parquet from row 0 to 3”, “content”:{“text”:{“2fe4b814-e676-5f31-838a-c0d9fd868c4c”:“On average, cats spend 2/3 of every day sleeping. That means a nine-year-old cat has been awake for only three years of its life.”, “079b5a19-ab2f-5cd8-ab7f-64e22cbfec86”:“Unlike dogs, cats do not have a sweet tooth. Scientists believe this is due to a mutation in a key taste receptor.”, “640c3b8a-813c-50b5-b030-6757207d85c1”:“When a cat chases its prey, it keeps its head level. Dogs and humans bob their heads up and down.”}}}

The query in the url starts with ? and different queries are concatenated with &. The parameter start_ix has a default value 0 so it need not be passed in the query.

2.3 Requests with Body

A request or response can have a body associated with them. Request body is used when the client need to pass some data to the server. While it is allowed to pass data using GET method, it is discouraged and the body should be sent using one of the POST, PUT, DELETE, or PATCH.

Before the client sends a body, the server needs to know what data to expect and how the data is structure to appropriately handle it to the functions tasked to perform actions or to store the data. For this purpose, FastAPI allows defining the body using the python’s pydantic class. Using pydantic also comes with the data validation. So, if the data sent by the client is not in the appropriate format, the server would respond back with the error.

from fastapi import FastAPI
from pydantic import BaseModel

class Item(BaseModel):
    id: str
    text: str

app = FastAPI()

@app.post("/db/")
def save_data(item: Item):
    return {"message": "Hi Client! You passed the following data to save.",
            "content": item}

Sending the request

POST http://mainpath/db/
Content-Type: application/json

{"id": "2wj09", "text": "This is a POST request"}

produces the following.

POST

HTTP/1.1 200 OK date: Wed, 08 Apr 2026 13:41:33 GMT server: uvicorn content-length: 101 content-type: application/json connection: close

{ “message”: “Hi Client! You sent this data.”, “content”: { “id”: “2wj09”, “text”: “This is a POST request” } }