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.
Recommended Pattern
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:
-
Did the request succeed? (
success) -
What happened? (
message) -
What data or error should the client use? (
dataorerror)
This creates a predictable contract between the backend and frontend, reducing bugs and simplifying development.