This post demonstrates how to capture path parameters and JSON payload in Actix-web.
Path Parameter And JSON Payload
A path parameter is a type of parameter provided to an application as part of a URI in an HTTP Request. For instance, turreta.com/posts/1 wherein 1 is a path parameter value and may represent a Post ID. How to extract what from a URI is determined by the application. A JSON payload refers to the JSON content of an HTTP Request Body. When sending JSON, the HTTP Request must specify Content-Type=application/json as one of its headers.
Sample REST API Using Actix-Web
Assuming we have the following URL.
1 | HTTP PUT /person/{person_id} |
The JSON payload to send to the server using HTTP PUT and the URL.
1 2 3 4 | { "person_name": "Mike Tyson", "person_status": "active" } |
Rust and Actix-Web Codes
First, we need to update Cargo.toml and put in a dependency Actix-Web.
1 2 3 4 5 6 7 8 9 | [package] name = "actix-web-capture-param-and-payload" version = "0.1.0" authors = ["Karl San Gabriel"] edition = "2018" [dependencies] actix-web = "1.0.8" serde = { version = "1.0.101", features = ["derive"] } |
Next, we need 2 structs. The JSONPayload struct represents the JSON payload. It needs the Deserialize trait so the server codes can automatically deserialize JSON from an HTTP request into a struct instance. Meanwhile, the Response struct represents an empty HTTP response from the server.
1 2 3 4 5 6 7 8 9 10 | #[derive(Deserialize, Debug)] struct JSONPayload { person_name: String, person_status: String } #[derive(Serialize)] struct Response { } |
Next, we need a request handler to pick up the Path Parameter from the URL and JSON from the HTTP request body. To refer to each, we use web::Path and web::Json types as function parameters.
1 2 3 4 5 6 7 | fn handle_request(path_param: web::Path<(String)>, payload: web::Json<JSONPayload>) -> impl Responder { println!("Path param {}", path_param.into_inner()); println!("JSON Payload {:?}", payload); return web::Json(Response{}); } |
Finally, we need the main function to start Actix-Web from. Here we map the path /persons/{person_id} and HTTP PUT to the handle_request function
1 2 3 4 5 6 7 8 9 10 11 | fn main() { HttpServer::new(|| { App::new() .service(web::resource("/persons/{person_id}") .route(web::put().to(handle_request))) }) .bind("127.0.0.1:8088") .unwrap() .run() .unwrap(); } |
Test Codes
This is testing with PostMan. First, we set the HTTP headers Accept and Content-Type. Also, we specify the HTTP method PUT and the URL. The URL is localhost:8088/persons/1 where 1 is Person ID.
Next, we set the body to a JSON value.
Then, click the Send button to send the request to the server. When the Actix-Web application received the request, it outputs the following on the console.
Meanwhile, PostMan will receive an empty response.
Tested with Rust 1.37.0.