本文代码 https://github.com/tothis/rust-record/tree/main/test/actix-web

已集成功能

  • log4rs 集成
  • SQLx 集成
  • Actix Web CRUD

Cargo.toml

[package]
name = "actix-web-record"
version = "0.1.0"
authors = ["Li Lei <this.lilei@gmail.com>"]
edition = "2021"[dependencies]
serde = "1.0"
actix-web = "4.0"
dotenv = "0.15"
log = "0.4"
log4rs = "1.0"[dependencies.sqlx]
version = "0.5"
features = ["postgres","runtime-actix-rustls"
]

数据库结构

-- ----------------------------
-- Sequence structure for user_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."user_id_seq";
CREATE SEQUENCE "public"."user_id_seq"
INCREMENT 1
MINVALUE  1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER SEQUENCE "public"."user_id_seq" OWNER TO "postgres";-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS "public"."user";
CREATE TABLE "public"."user" ("id" int8 NOT NULL GENERATED BY DEFAULT AS IDENTITY (
INCREMENT 1
MINVALUE  1
MAXVALUE 9223372036854775807
START 1
CACHE 1
),"created_at" timestamp(6),"updated_at" timestamp(6),"deleted_at" timestamp(6),"name" varchar(255) COLLATE "pg_catalog"."default"
)
;
ALTER TABLE "public"."user" OWNER TO "postgres";-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."user_id_seq"
OWNED BY "public"."user"."id";
SELECT setval('"public"."user_id_seq"', 1, false);-- ----------------------------
-- Primary Key structure for table user
-- ----------------------------
ALTER TABLE "public"."user" ADD CONSTRAINT "user_pkey" PRIMARY KEY ("id");

.env

DATABASE_URL="postgres://postgres:123456@127.0.0.1/actix_web_record"

config/log4rs.yaml

refresh_rate: 30 seconds
appenders:stdout:kind: consoleencoder:pattern: "{d(%F %H:%M:%S%.f)} - {m}{n}"main:kind: filepath: "test/actix-web/log/main.log"encoder:pattern: "{d(%F %H:%M:%S%.f)} - {m}{n}"
root:level: warnappenders:- stdout
loggers:main:level: infoappenders:- main- stdoutadditive: false

src/handler/user.rs

use actix_web::{delete, get, post, Responder, web};
use actix_web::web::Data;
use serde::{Deserialize, Serialize};
use sqlx::{PgPool, query, query_as};
use web::{Json, Path};use crate::handler::result::{none, some};#[derive(Serialize)]
struct GetUserResult {id: i64,name: Option<String>,
}#[derive(Deserialize)]
pub struct SaveUserQuery {id: Option<i64>,name: Option<String>,
}#[get("user")]
pub async fn all(data: Data<PgPool>
) -> impl Responder {some(query_as!(GetUserResult,r#"select id, name from "user" where deleted_at is null"#).fetch_all(data.get_ref()).await)
}#[get("user/{id}")]
pub async fn get(data: Data<PgPool>,path: Path<i64>,
) -> impl Responder {let id = path.into_inner();some(query_as!(GetUserResult,r#"select id, name from "user" where deleted_at is null and id = $1"#,id).fetch_one(data.get_ref()).await)
}#[post("user")]
pub async fn post(data: Data<PgPool>,Json(v): Json<SaveUserQuery>,
) -> impl Responder {none(match v.id {None => query!(r#"insert into "user" (name, created_at) values ($1, now())"#,v.name).execute(data.get_ref()).await,Some(id) => query!(r#"update "user" set name = $1, updated_at = now() where deleted_at is null and id = $2"#,v.name,id).execute(data.get_ref()).await})
}#[delete("user/{id}")]
pub async fn delete(data: Data<PgPool>,path: Path<i64>,
) -> impl Responder {let id = path.into_inner();none(query!(r#"update "user" set deleted_at = now() where id = $1"#,id).execute(data.get_ref()).await)
}

src/handler/mod.rs

use actix_web::http::header::CONTENT_TYPE;
use actix_web::Responder;
use actix_web::web;
use serde::{Deserialize, Serialize};mod user;pub const APPLICATION_JSON: &str = "application/json";pub fn route(config: &mut web::ServiceConfig) {config.service(user::all);config.service(user::get);config.service(user::post);config.service(user::delete);
}pub async fn default_route() -> impl Responder {r#"{"code":"0","message":"404 Not Found"}"#.customize().insert_header((CONTENT_TYPE, APPLICATION_JSON))
}#[derive(Serialize, Deserialize)]
pub struct HttpResult<T> {code: u8,#[serde(skip_serializing_if = "Option::is_none")]data: Option<T>,#[serde(skip_serializing_if = "String::is_empty")]message: String,
}mod result {use std::fmt::Display;use actix_web::web::Json;use log::error;use crate::handler::HttpResult;fn err<T, M: Display>(message: M) -> Json<HttpResult<T>> {let message = message.to_string();error!(target: "main", "{}", message);Json(HttpResult { code: 1, data: None, message })}/// 响应数据pub fn some<T, E: Display>(v: crate::Result<T, E>) -> Json<HttpResult<T>> {match v {Ok(o) => Json(HttpResult {code: 0,data: Some(o),message: "".into(),}),Err(e) => err(e)}}/// 不响应数据pub fn none<T, E: Display>(v: crate::Result<T, E>) -> Json<HttpResult<()>> {match v {Ok(_) => Json(HttpResult {code: 0,data: None,message: "".into(),}),Err(e) => err(e)}}
}

main.rs

use std::env;
use std::error::Error;
use std::result::Result as StdResult;use actix_web::{App, HttpServer};
use actix_web::web::{Data, route};
use dotenv::dotenv;
use log4rs;
use log::info;
use sqlx::PgPool;mod handler;pub type Result<T = (), E = Box<dyn Error>> = StdResult<T, E>;#[actix_web::main]
async fn main() -> Result {dotenv().ok();log4rs::init_file("config/log4rs.yaml", Default::default())?;let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;info!(target: "main", "程序启动");HttpServer::new(move ||App::new().app_data(Data::new(pool.clone())).default_service(route().to(handler::default_route)).configure(handler::route)).bind(("127.0.0.1", 8080))?.run().await?;Ok(())
}

Actix Web SQLx 搭建 Web 后端服务相关推荐

  1. ginapi服务器性能,基于gin web框架搭建RESTful API服务

    这篇主要学习go项目中的项目结构.项目规范等知识,ROM采用的database/sql的写法. 1.技术框架 利用的是ginweb框架,然后ROM层选用database/sql,安装mysql驱动.安 ...

  2. 文件web服务器搭建,Web服务器的构建和配置

    利用windows server2003中iis构建web服务器的几种方法.下面是学习啦小编跟大家分享的是Web 服务器的构建和配置,欢迎大家来阅读学习. Web 服务器的构建和配置 工具/原料 wi ...

  3. 服务器网站集成环境哪个好,如何搭建Web服务器之集成环境

    WEB服务器简介 WEB服务器,即网站服务器,也称为WWW(WORLD WIDE WEB)服务器,是指驻留于因特网上某种类型计算机的程序.主要功能是提供网上信息浏览服务.目前最主流的三个Web服务器是 ...

  4. Python之简易Web框架搭建

    Python之简易Web框架搭建 Web框架介绍 WSGI协议 Web框架开发 项目结构 MyWebServer.py 之前的静态服务器代码 WSGI协议的要求 更新代码 framework.py 返 ...

  5. c++实现简单的web服务器搭建

    c++简单的web服务器搭建 web 服务器与 Http 协议 Web 浏览器(Web Browser)是一个用于文档检索和显示的客户应用程序,并通过超文本传输协议 Http(Hyper Text T ...

  6. 函数计算搭建小程序Web应用后端服务

    简介:使用Severless架构搭建移动App.小程序和Web应用后端服务,弹性伸缩使用云资源. 直达最佳实践:[函数计算搭建小程序Web应用后端服务] 最佳实践频道:[点击查看更多上云最佳实践] 这 ...

  7. [零基础,全开源]基于web的远程深度学习服务搭建

    所有代码和工具均已开源.关注"DL工程实践",后台回复"web",自动获取. 1.背景介绍 目前有很多的深度学习推理方案,不过大多是离线部署的.这方面可以利用的 ...

  8. 普歌-腾讯云短信+使用node发送短信(3种方法API、SDK)、封装工具、搭建web服务、写接口、调用接口发送短信、时效性判断、验证验证码的正确性(下)

    普歌-结合腾讯云短信服务+node搭建一个简单的发送短信web小项目 涉及技术: 腾讯云服务 后端服务:node+express 前端搭建:html+js 前言:本来这篇博客应该很早就发了,中间有一些 ...

  9. RHEL 5服务篇—使用Apache搭建web服务(四)部署AWStats网站分析系统

    在httpd服务器的访问日志文件access_log中,记录了大量的客户机访问信息,通过分析这些信息,可以及时了解web站点的访问情况.但是由于access_log文件记录的信息太多,查看起来很不方便 ...

最新文章

  1. leetCode C++ 49. 字母异位词分组 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
  2. 记录不认识的英文单词
  3. java中的Calendar
  4. GDCM:dicom文件的临床试验注释的测试程序
  5. viewpager+fragment学习笔记
  6. JS中代表结束的三个关键字 break,continue,return
  7. Mybatis框架中SqlSessionFactory
  8. 深夜福利, 小试linuxkit
  9. word排版插件_8款堪称神器的Office插件,让你工作效率直线飙升!
  10. mysql amp;amp;_浅析mysql交互式连接amp;非交互式连接
  11. 华为计算机充电指示灯,数码产品:华为p40充电指示灯不亮在哪里设置 有指示灯吗...
  12. yyuc视图未更新,控制器修改可以看到,视图无法更新,提示Allowed memory size of exhausted
  13. 检测文章相似度的方法?文章原创度检测工具免费
  14. 软考网络工程师基础知识
  15. 基于微信小程序的信访投诉系统开发与实现
  16. 中秋节快到了,一起用MATLAB绘制一款2.5D月饼叭
  17. 2022-2028年全球与中国近红外光谱仪行业竞争格局与投资战略研究
  18. python coding style guide 的快速落地实践
  19. java单根结构_对象导论:单根继承结构
  20. Android与Unity的交互

热门文章

  1. 简单socket 聊天室 C/S模式 小例子
  2. 拥有全球七亿用户数据的墨迹赤必,能用天气服务为企业带来什么新气象?
  3. CQF项目课程学习介绍(一)
  4. 怎样理解Verilog中的assign?
  5. 第一周项目2 计算长方体的表面积和表面积
  6. 使用EDTA进行TE注释
  7. 一个程序员对另一个程序员的忠告
  8. 一文看懂25个神经网络模型
  9. 使用SQL语句修改MYSQL数据库密码
  10. U盘启动无法使用键盘与鼠标