Files
python-doc/Docs/Libs/FastAPI/04-Post-Method.md
2026-05-13 17:00:43 +03:30

6.3 KiB
Raw Blame History

FastAPI POST Endpoint and JSON Input

Overview

This document explains how to create a POST endpoint in FastAPI for adding new users. It covers two approaches:

  1. Sending input as query parameters
  2. Sending input as a JSON request body using a Pydantic model

For real API development, the Pydantic model approach is recommended because it provides a cleaner structure, better validation, and more realistic request handling.


1. Example Application Using Query Parameters

Create or update main.py with the following code:

from fastapi import FastAPI

app = FastAPI()

users = [
    {"name": "abbas", "age": 20},
    {"name": "mmd", "age": 37},
    {"name": "asghar", "age": 19},
]


@app.get("/")
def home_page():
    return {"msg": "API is working"}


@app.post("/new_user")
def create_user(name: str, age: int):
    new_user = {"name": name, "age": age}
    users.append(new_user)
    return {"msg": "User created successfully"}

Explanation

@app.post("/new_user")
def create_user(name: str, age: int):

This registers a POST endpoint at:

POST /new_user

The endpoint receives two parameters:

name: str
age: int

FastAPI automatically validates the input types. If age is not an integer, FastAPI returns a validation error.

Example Request

curl -X POST "http://localhost:8000/new_user?name=ali&age=25"

Example Response

{
  "msg": "User created successfully"
}

Important Note

In this version, the data is sent through query parameters, not as a JSON body.

This is acceptable for simple testing, but it is not the best practice for real APIs that create resources.


2. Recommended Application Using JSON Body

A better approach is to define a Pydantic model and receive the user data as JSON.

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


class User(BaseModel):
    name: str
    age: int


users = [
    {"name": "abbas", "age": 20},
    {"name": "mmd", "age": 37},
    {"name": "asghar", "age": 19},
]


@app.get("/")
def home_page():
    return {"msg": "API is working"}


@app.post("/new_user")
def create_user(user: User):
    new_user = {"name": user.name, "age": user.age}
    users.append(new_user)
    return {"msg": "User created successfully"}

Explanation

class User(BaseModel):
    name: str
    age: int

This creates a request model named User.

The model defines the expected structure of the JSON input:

{
  "name": "ali",
  "age": 25
}

FastAPI uses this model to:

Validate incoming data Convert JSON into a Python object Generate automatic API documentation Return useful validation errors when input is invalid


3. POST Endpoint Definition

@app.post("/new_user")
def create_user(user: User):

This creates a POST endpoint at:

POST /new_user

The endpoint expects a JSON request body matching the User model.


4. Creating a New Resource

new_user = {"name": user.name, "age": user.age}
users.append(new_user)

This code creates a new dictionary using the received request data and appends it to the users list.

The users list acts as temporary in-memory storage.

This simulates inserting a new record into a database.


5. Returning a JSON Response

return {"msg": "User created successfully"}

FastAPI automatically converts the returned dictionary into a JSON response.

Example response:

{
  "msg": "User created successfully"
}

6. Example Request Using curl

curl -X POST "http://localhost:8000/new_user" \
  -H "Content-Type: application/json" \
  -d '{"name": "ali", "age": 25}'

Response

{
  "msg": "User created successfully"
}

7. Verifying the Result

To verify that the user was added, you should also define a GET /users endpoint.

@app.get("/users")
def get_users():
    return users

Then send this request:

GET /users

Example response:

[
  {
    "name": "abbas",
    "age": 20
  },
  {
    "name": "mmd",
    "age": 37
  },
  {
    "name": "asghar",
    "age": 19
  },
  {
    "name": "ali",
    "age": 25
  }
]

8. Complete Recommended Version

from fastapi import FastAPI, status
from pydantic import BaseModel

app = FastAPI()


class User(BaseModel):
    name: str
    age: int


users = [
    {"name": "abbas", "age": 20},
    {"name": "mmd", "age": 37},
    {"name": "asghar", "age": 19},
]


@app.get("/")
def home_page():
    return {"msg": "API is working"}


@app.get("/users")
def get_users():
    return users


@app.post("/new_user", status_code=status.HTTP_201_CREATED)
def create_user(user: User):
    new_user = {"name": user.name, "age": user.age}
    users.append(new_user)

    return {
        "msg": "User created successfully",
        "user": new_user
    }

9. Running the Application

Start the FastAPI application using uvicorn:

uvicorn main:app --reload

The API will run at:

http://localhost:8000

Interactive API documentation will be available at:

http://localhost:8000/docs

10. Best Practices

Use POST requests when creating new resources.

Use Pydantic models for request bodies instead of query parameters.

Return proper HTTP status codes, such as:

201 Created

Do not use in-memory lists for production data storage.

Use a real database such as PostgreSQL, MySQL, or MongoDB in production.

Validate and sanitize all client-provided input.

Keep model names clear and professional. For example, use User instead of user_class.

Return meaningful responses that include the created resource when useful.

Use /docs to test and verify API behavior during development.


11. Production Note for DevOps

The in-memory users list is reset every time the application restarts. In production environments, application data must be stored in a persistent database.

For production deployment, the FastAPI application should usually run behind a process manager and reverse proxy, such as:

Gunicorn / Uvicorn workers
Nginx or Traefik
Docker or Kubernetes
PostgreSQL or another persistent database

The development command:

uvicorn main:app --reload

should not be used in production because --reload is intended only for local development.