zhaopinxinle.com

Creating an HTTP Request Visualizer with Rust: Final Steps

Written on

Chapter 1: Introduction to HTTP Request Visualization

This piece concludes our two-part series on developing an HTTP request visualizer using Rust. To grasp the concepts discussed here, we highly recommend reviewing the first part of our series for a thorough understanding of the project's evolution. You can find the previous section through the link provided below.

We will now implement the POST, PUT, and DELETE endpoints to handle various types of HTTP requests.

Chapter 2: Implementing the POST Endpoint

The POST endpoint is tasked with managing POST requests. It retrieves all values from the request body, excluding multimedia content such as images, videos, and audio files, while also defining header requests and processing query parameters.

To set this up:

  1. Create a file named post.rs within the src directory.
  2. Add the following code to post.rs:

use crate::utils::{get_body_data, get_req_headers, QParams, ResponseData};

use actix_web::{

post,

web::{Bytes, Query},

HttpRequest, HttpResponse,

};

#[post("/post")]

pub async fn post_responder(req: HttpRequest, bytes: Bytes, query: Query<QParams>) -> HttpResponse {

let body_data = get_body_data(&bytes);

let headers = get_req_headers(&req);

let response_data = ResponseData::new()

.message("Request successful")

.status_code("201".to_string())

.method(crate::utils::Method::POST)

.body(body_data)

.queries(query)

.headers(headers);

HttpResponse::Created().json(response_data)

}

In this code snippet, we define the post_responder function, which processes POST requests at the "/post" endpoint. It accepts three parameters: req (the HTTP request), bytes (the request body), and query (the query parameters). Within the function:

  • We extract information from the request body and headers through utility functions.
  • We construct a response object that includes a message, a status code, the request method, body data, query parameters, and headers.
  • Finally, we return an HTTP response with a 201 (Created) status code and the response data formatted as JSON.

It's crucial to note that we're simulating the typical server response behavior with a 201 status code. However, we are not storing this data in a database or a file.

Chapter 3: Implementing the PUT Endpoint

The PUT endpoint is designated for updating resources via the "/put" endpoint. It collects all relevant header, body, and query parameters to return them in a successful response.

To implement this:

  1. Create a file named put.rs in the src directory.
  2. Add the following code to put.rs:

use crate::utils::{get_body_data, get_req_headers, QParams, ResponseData};

use actix_web::{

put,

web::{Bytes, Query},

HttpRequest, HttpResponse,

};

#[put("/put")]

pub async fn put_responder(req: HttpRequest, bytes: Bytes, query: Query<QParams>) -> HttpResponse {

let body_data = get_body_data(&bytes);

let headers = get_req_headers(&req);

let response_data = ResponseData::new()

.message("Request successful")

.status_code("200".to_string())

.method(crate::utils::Method::PUT)

.body(body_data)

.queries(query)

.headers(headers);

HttpResponse::Ok().json(response_data)

}

This code outlines the put_responder function, which manages PUT requests directed to the "/put" endpoint. Similar to the POST endpoint, it extracts data from the request body and headers and constructs a response object. The function returns an HTTP response with a 200 (OK) status code and the response data in JSON format.

Chapter 4: Implementing the DELETE Endpoint

The DELETE endpoint is responsible for removing resources via the "/delete" endpoint. It retrieves all header, body, and query parameters and sends them back in a successful response.

To set this up:

  1. Create a file named delete.rs in the src directory.
  2. Add the following code to delete.rs:

use crate::utils::{get_body_data, get_req_headers, QParams, ResponseData};

use actix_web::{

delete,

web::{Bytes, Query},

HttpRequest, HttpResponse,

};

#[delete("/delete")]

pub async fn delete_responder(req: HttpRequest, bytes: Bytes, query: Query<QParams>) -> HttpResponse {

let body_data = get_body_data(&bytes);

let headers = get_req_headers(&req);

let response_data = ResponseData::new()

.message("Request successful")

.status_code("200".to_string())

.method(crate::utils::Method::DELETE)

.body(body_data)

.queries(query)

.headers(headers);

HttpResponse::Ok().json(response_data)

}

This code defines the delete_responder function that processes DELETE requests at the "/delete" endpoint. Similar to the previous functions, it extracts data from the request and constructs a response object, returning an HTTP response with a 200 (OK) status code and the response data in JSON format.

Chapter 5: Integrating Handlers into the Main Application

Next, we need to register all the handlers defined in the separate files within the main.rs file to allow our application to utilize them.

In your main.rs file, include the following code:

mod delete;

mod env;

mod get;

mod post;

mod put;

mod utils;

use crate::delete::delete_responder;

use crate::env::{app_port, load_config};

use crate::get::{get_responder, health_check};

use crate::post::post_responder;

use crate::put::put_responder;

use actix_cors::Cors;

use actix_web::middleware;

use actix_web::{middleware::Logger, App, HttpServer};

#[actix_web::main]

async fn main() -> std::io::Result<()> {

load_config();

println!("Starting application...");

println!("Server running on PORT {:?}", app_port());

HttpServer::new(move || {

let cors = Cors::default()

.allow_any_origin()

.send_wildcard()

.allowed_headers(vec!["content-type", "authorization"])

.allowed_methods(vec!["GET", "POST", "PUT", "DELETE"])

.max_age(3600);

App::new()

.wrap(middleware::Logger::default())

.wrap(cors)

.wrap(Logger::default())

.service(health_check)

.service(get_responder)

.service(post_responder)

.service(put_responder)

.service(delete_responder)

})

.bind(("0.0.0.0", app_port()))?

.run()

.await

}

Once you run cargo run in your terminal, your server should be operational locally, ready to handle requests from the frontend or via tools like curl.

The code discussed in this article is available on GitHub. If you have any suggestions or encounter issues, please feel free to submit a pull request. Contributions are always welcome!

Thank you for sticking with us through this article. If you found it insightful, please share it with others in the community. Rustaceans 🚀

Thank you for being part of the Rustaceans community! Before you leave, show your appreciation by clapping and following our publication. Interested in writing for us? Connect with us on X or sign up for the Rust Bytes Newsletter, or consider buying us a coffee.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

# Understanding and Overcoming Thinking Traps for a Healthier Mind

Explore common thinking traps that lead to negative thoughts and discover ways to overcome them for improved mental health.

Exploring the Wonders of Jellyfish and Synthetic Biology

Dive into the latest discoveries in synthetic biology, including jellyfish proteins and new DNA barcode systems.

# Overcoming Smartphone Addiction: My Journey to Freedom

Discover effective strategies that helped me break free from smartphone addiction and reclaim my life.