Consistent API Response Structure (Flask REST API)

Why Use a Consistent Response Format?

A common mistake in APIs is returning different response structures from different endpoints.

Bad Example

Success:

{
    "id": 1,
    "name": "John Doe"
}

Error:

{
    "message": "Student not found"
}

The frontend must guess what the response looks like for every endpoint.


Return the same top-level structure for every API response.

Success Response

{
    "success": true,
    "message": "Student retrieved successfully",
    "data": {
        "id": 1,
        "name": "John Doe"
    }
}

Error Response

{
    "success": false,
    "message": "Student not found",
    "error": "STUDENT_NOT_FOUND"
}

Benefits

1. Predictable Responses

Every endpoint follows the same format.

{
    "success": true|false,
    "message": "...",
    "data": {},
    "error": "..."
}

2. Cleaner Frontend Code

Instead of checking different response shapes:

if (response.data.message === "Student not found") {
    // handle error
}

Use:

if (!response.data.success) {
    // handle error
}

3. Easier Debugging

Error codes make issues easier to identify.

{
    "success": false,
    "message": "Student not found",
    "error": "STUDENT_NOT_FOUND"
}
{
    "success": false,
    "message": "Unauthorized access",
    "error": "UNAUTHORIZED"
}
{
    "success": false,
    "message": "Database error occurred",
    "error": "DATABASE_ERROR"
}

4. Better Scalability

As the application grows, all endpoints remain consistent, making maintenance and frontend integration simpler.


Suggested API Templates

GET Success

return {
    "success": True,
    "message": "Student retrieved successfully",
    "data": student.to_dict()
}, 200

GET Not Found

return {
    "success": False,
    "message": "Student not found",
    "error": "STUDENT_NOT_FOUND"
}, 404

POST Success

return {
    "success": True,
    "message": "Student created successfully",
    "data": student.to_dict()
}, 201

Validation Error

return {
    "success": False,
    "message": "Email already exists",
    "error": "EMAIL_ALREADY_EXISTS"
}, 409

Server Error

return {
    "success": False,
    "message": "Internal server error",
    "error": "SERVER_ERROR"
}, 500

Rule of Thumb

Every API response should answer these three questions:

  1. Did the request succeed? (success)

  2. What happened? (message)

  3. What data or error should the client use? (data or error)

This creates a predictable contract between the backend and frontend, reducing bugs and simplifying development.

Powered by Forestry.md