useactix_web::middleware::Logger;useactix_web::{ error, get, post,web::{self,Json,ServiceConfig},Result,};useserde::{Deserialize,Serialize};useshuttle_actix_web::ShuttleActixWeb;useshuttle_runtime::{CustomError};usesqlx::{Executor,FromRow,PgPool};#[get("/{id}")]asyncfnretrieve(path:web::Path<i32>, state:web::Data<AppState>)->Result<Json<Todo>>{// query database to get data// if error, return Bad Request HTTP status codelet todo =sqlx::query_as("SELECT * FROM todos WHERE id = $1").bind(*path).fetch_one(&state.pool).await.map_err(|e|error::ErrorBadRequest(e.to_string()))?;Ok(Json(todo))}#[post("")]asyncfnadd(todo:web::Json<TodoNew>, state:web::Data<AppState>)->Result<Json<Todo>>{// query database to create a new record using the request body// if error, return Bad Request HTTP status codelet todo =sqlx::query_as("INSERT INTO todos(note) VALUES ($1) RETURNING id, note").bind(&todo.note).fetch_one(&state.pool).await.map_err(|e|error::ErrorBadRequest(e.to_string()))?;Ok(Json(todo))}#[derive(Clone)]structAppState{ pool:PgPool,}#[shuttle_runtime::main]asyncfnactix_web(#[shuttle_shared_db::Postgres] pool:PgPool,)->ShuttleActixWeb<implFnOnce(&mutServiceConfig)+Send+Clone+'static>{// run migrations pool.execute(include_str!("../schema.sql")).await.map_err(CustomError::new)?;// set up AppStatelet state =web::Data::new(AppState{ pool });// set up our Actix web service and wrap it with logger and add the AppState as app datalet config =move|cfg:&mutServiceConfig|{ cfg.service(web::scope("/todos").wrap(Logger::default()).service(retrieve).service(add).app_data(state),);};Ok(config.into())}#[derive(Deserialize)]structTodoNew{pub note:String,}#[derive(Serialize, Deserialize, FromRow)]structTodo{pub id:i32,pub note:String,}
Once you’ve cloned the example, try launching it locally using shuttle run. Once you’ve verified that it runs successfully, try using cURL in a new terminal to send a POST request:
curl-X POST -d'{"note":"Hello world!"}'-H'Content-Type: application/json'\ http://localhost:8000/todo
Assuming the request was successful, you’ll get back a JSON response with the ID and Note of the record you just created. If you try the following cURL command, you should be able to then retrieve the message you stored:
curl http://localhost:8000/todo/<id>
Interested in extending this example? Here’s as couple of ideas:
Add update and delete routes
Add static files to show your records
If you want to explore other frameworks, we have more examples with popular ones like Tower and Warp. You can find them right here.
Be sure to check out the examples repo for many more examples!