DEV Community

Cover image for HTTP Responses: A Quick Guide With Best Practices
Sotiris Kourouklis
Sotiris Kourouklis

Posted on • Originally published at sotergreco.com

HTTP Responses: A Quick Guide With Best Practices

While creating APIs, handling requests and responses might seem easy at first glance, but the best practices behind each request and response are far from what the developer might believe.

This article is going to explain what a response should return to inform the frontend in the best way possible and what information should be included in each response and why.

Also, we are going to see some architecture best practices to help you protect your API from attacks or other harmful activities.

What Are HTTP Responses

An HTTP response is usually a json object when we are talking for API's that is send from the server to the client after a series of computations or algorithms, that best represent the current state of the server.

{
  "status": 200,
  "data": {
    // my data here
  }
}
Enter fullscreen mode Exit fullscreen mode

It is informative and representative about what happend after the Request a client has made.

Types Of Responses and Statuses

Each response has a specific type represented by a number. You all have seen 500 or 404 responses, but there are many different statuses that you should use for each scenario.

Each one of them is grouped by hundreds, so that means 400, 401, 402 have something in common. The same goes for 500, 501, 503, etc.

  • Status 100 -> Information responses

  • Status 200 -> Successful responses

  • Status 300 -> Redirection messages

  • Status 400 -> Client error responses

  • Status 500 -> Server error responses

If you want a more detailed explanation for all of the statuses you can check MDN Docs

Structuring Responses

Now that we know what HTTP Responses are we need a way to structure them the best way we can in order to give as many details to the client as possible. Usually a common best practice is to always return the status of the response together with the response body.

That not only informs the client for how the response went but also can use the status to display his own success or failure messages on the frontend.

// https://api.test.com/api/v1/auth/login
{
  "status": 200,
  "data": {
    "token": "eyJhbGciOiJIUzUxMiJ9",
    "refresh_token": "eyJhbGciOiJIUzU",
    "user": {
      "id": "01HYZK7V9BXM0G1KZ8H3T9JNQ9",
      "username": "test@gmail.com",
      "email": "test@gmail.com",
      "nickname": "TestUser",
      "firstname": "Test",
      "lastname": "Test",
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Extra Information

Another useful addition for your responses can be ?extra_data=1 which is basically added to the URL and return extra information about the request.

// https://api.test.com/api/v1/auth/login?extra_data=1
{
  "status": 200,
  "extra_data": {
    "timestamp": "2024-05-28T12:34:56Z",
    "response_size": 512,
    "request_id": "abc123xyz",
    "processing_time_ms": 123,
    "server_info": "Server-1",
    "client_ip": "192.168.1.100",
    "api_version": "v1.2.3",
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
  },
  "data": {
    "token": "eyJhbGciOiJIUzUxMiJ9",
    "refresh_token": "eyJhbGciOiJIUzU",
    "user": {
      "id": "01HYZK7V9BXM0G1KZ8H3T9JNQ9",
      "username": "test@gmail.com",
      "email": "test@gmail.com",
      "nickname": "TestUser",
      "firstname": "Test",
      "lastname": "Test",
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Error Responses

Error responses are crucial for informing the client about issues encountered during request processing. These responses should include a clear status code from the 400 or 500 range, a descriptive error message, and any additional details that could help diagnose the problem.

For example, a 404 status code indicates that the requested resource was not found, while a 500 status code signals an internal server error.

Best Practices for Error Responses

When structuring error responses, it's essential to follow some best practices to ensure clarity. Always include the status code, a message, and any relevant data that can help debug the issue. For instance:

{
    "status": 404,
    "error": "Not Found",
    "message": "The requested resource could not be found.",
    "path": "/api/resource",
    "timestamp": "2023-10-01T12:00:00Z"
}
Enter fullscreen mode Exit fullscreen mode

In addition to the standard fields, consider adding extra information that could be beneficial for debugging, such as a unique error code, a link to documentation, or a correlation ID for tracing the request through logs. For example:

{
    "status": 500,
    "error": "Internal Server Error",
    "message": "An unexpected error occurred.",
    "error_code": "INTERNAL_ERROR_500",
    "documentation_url": "https://api.example.com/docs/errors/500",
    "correlation_id": "abc123xyz",
    "timestamp": "2023-10-01T12:00:00Z"
}
Enter fullscreen mode Exit fullscreen mode

Final Words

In conclusion, effectively handling HTTP responses is vital for creating robust and user-friendly APIs. By structuring responses clearly, including necessary status codes, and providing detailed error messages, you can greatly enhance the client experience.

Following best practices and adding extra information for error responses will not only help in debugging but also ensure that your API is resilient and secure. By adhering to these guidelines, you can build reliable APIs that effectively communicate with the frontend, making your applications more efficient and easier to maintain.

Thanks for reading, and I hope you found this article helpful. If you have any questions, feel free to email me at kourouklis@pm.me, and I will respond.

You can also keep up with my latest updates by checking out my X here: x.com/sotergreco

Top comments (0)