mirror of
https://github.com/actix/examples
synced 2025-01-23 06:14:35 +01:00
Merge pull request #238 from bikeshedder/async_pg_better_instructions
Improve async_pg example
This commit is contained in:
commit
e4d79472e9
1
async_pg/.gitignore
vendored
1
async_pg/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
.env
|
||||||
|
@ -4,12 +4,13 @@ version = "0.1.0"
|
|||||||
authors = ["dowwie <dkcdkg@gmail.com>"]
|
authors = ["dowwie <dkcdkg@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.0.0"
|
||||||
actix-web = "2.0.0"
|
actix-web = "2.0.0"
|
||||||
deadpool-postgres = "0.4.3"
|
config = "0.10.1"
|
||||||
|
deadpool-postgres = "0.5.0"
|
||||||
derive_more = "0.99.2"
|
derive_more = "0.99.2"
|
||||||
|
dotenv = "0.15.0"
|
||||||
serde = { version = "1.0.104", features = ["derive"] }
|
serde = { version = "1.0.104", features = ["derive"] }
|
||||||
tokio-pg-mapper = "0.1.4"
|
tokio-pg-mapper = "0.1.4"
|
||||||
tokio-pg-mapper-derive = "0.1.4"
|
tokio-pg-mapper-derive = "0.1.4"
|
||||||
|
@ -1,12 +1,72 @@
|
|||||||
This example illustrates:
|
# async_pg example
|
||||||
- tokio_postgres
|
|
||||||
- use of tokio_pg_mapper for postgres data mapping
|
|
||||||
- deadpool_postgres for connection pooling
|
|
||||||
|
|
||||||
|
## This example illustrates
|
||||||
|
|
||||||
# Instructions
|
- `tokio_postgres`
|
||||||
1. Set up the testing database by running /sql/create_db.sh
|
- use of `tokio_pg_mapper` for postgres data mapping
|
||||||
2. `cargo run`
|
- `deadpool_postgres` for connection pooling
|
||||||
3. from the command line (linux), POST a user to the endpoint:
|
- `dotenv` + `config` for configuration
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
1. Create database user
|
||||||
|
|
||||||
|
```shell
|
||||||
|
createuser -P test_user
|
||||||
|
```
|
||||||
|
|
||||||
|
Enter a password of your choice. The following instructions assume you
|
||||||
|
used `testing` as password.
|
||||||
|
|
||||||
|
This step is **optional** and you can also use an existing database user
|
||||||
|
for that. Just make sure to replace `test_user` by the database user
|
||||||
|
of your choice in the following steps and change the `.env` file
|
||||||
|
containing the configuration accordingly.
|
||||||
|
|
||||||
|
2. Create database
|
||||||
|
|
||||||
|
```shell
|
||||||
|
createdb -O test_user testing_db
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Initialize database
|
||||||
|
|
||||||
|
```shell
|
||||||
|
psql -f sql/schema.sql testing_db
|
||||||
|
```
|
||||||
|
|
||||||
|
This step can be repeated and clears the database as it drops and
|
||||||
|
recreates the schema `testing` which is used within the database.
|
||||||
|
|
||||||
|
4. Create `.env` file:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
SERVER_ADDR=127.0.0.1:8080
|
||||||
|
PG.USER=test_user
|
||||||
|
PG.PASSWD=testing
|
||||||
|
PG.HOST=127.0.0.1
|
||||||
|
PG.PORT=5432
|
||||||
|
PG.DBNAME=testing_db
|
||||||
|
PG.POOL.MAX_SIZE=16
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Run the server:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Using a different terminal send an HTTP POST request to the running server:
|
||||||
|
|
||||||
|
```shell
|
||||||
echo '{"email": "ferris@thecrab.com", "first_name": "ferris", "last_name": "crab", "username": "ferreal"}' | http -f --json --print h POST http://127.0.0.1:8080/users
|
echo '{"email": "ferris@thecrab.com", "first_name": "ferris", "last_name": "crab", "username": "ferreal"}' | http -f --json --print h POST http://127.0.0.1:8080/users
|
||||||
- a unique constraint exists for username, so running this twice will return a 500
|
```
|
||||||
|
|
||||||
|
**...or using curl...**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl -d '{"email": "ferris@thecrab.com", "first_name": "ferris", "last_name": "crab", "username": "ferreal"}' -H 'Content-Type: application/json' http://127.0.0.1:8080/users
|
||||||
|
```
|
||||||
|
|
||||||
|
A unique constraint exists for username, so sending this request twice
|
||||||
|
will return an internal server error (HTTP 500).
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
psql -U postgres -h 127.0.0.1 -f setup_db_and_user.sql
|
|
@ -1,15 +1,6 @@
|
|||||||
DROP DATABASE IF EXISTS testing_db;
|
|
||||||
|
|
||||||
CREATE USER test_user WITH PASSWORD 'testing';
|
|
||||||
|
|
||||||
CREATE DATABASE testing_db OWNER test_user;
|
|
||||||
|
|
||||||
\connect testing_db;
|
|
||||||
|
|
||||||
DROP SCHEMA IF EXISTS testing CASCADE;
|
DROP SCHEMA IF EXISTS testing CASCADE;
|
||||||
CREATE SCHEMA testing;
|
CREATE SCHEMA testing;
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE testing.users (
|
CREATE TABLE testing.users (
|
||||||
id BIGSERIAL PRIMARY KEY,
|
id BIGSERIAL PRIMARY KEY,
|
||||||
email VARCHAR(200) NOT NULL,
|
email VARCHAR(200) NOT NULL,
|
@ -1,3 +1,20 @@
|
|||||||
|
mod config {
|
||||||
|
use serde::Deserialize;
|
||||||
|
pub use ::config::ConfigError;
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub server_addr: String,
|
||||||
|
pub pg: deadpool_postgres::Config,
|
||||||
|
}
|
||||||
|
impl Config {
|
||||||
|
pub fn from_env() -> Result<Self, ConfigError> {
|
||||||
|
let mut cfg = ::config::Config::new();
|
||||||
|
cfg.merge(::config::Environment::new())?;
|
||||||
|
cfg.try_into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod models {
|
mod models {
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio_pg_mapper_derive::PostgresMapper;
|
use tokio_pg_mapper_derive::PostgresMapper;
|
||||||
@ -88,31 +105,25 @@ mod handlers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
use actix_web::{web, App, HttpServer};
|
use actix_web::{web, App, HttpServer};
|
||||||
use deadpool_postgres::{Manager, Pool};
|
use dotenv::dotenv;
|
||||||
use handlers::add_user;
|
use handlers::add_user;
|
||||||
use tokio_postgres::{Config, NoTls};
|
use tokio_postgres::NoTls;
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
const SERVER_ADDR: &str = "127.0.0.1:8080";
|
dotenv().ok();
|
||||||
|
|
||||||
let pg_config = "postgres://test_user:testing@127.0.0.1:5432/testing_db"
|
let config = crate::config::Config::from_env().unwrap();
|
||||||
.parse::<Config>()
|
let pool = config.pg.create_pool(NoTls).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let pool = Pool::new(
|
|
||||||
Manager::new(pg_config, NoTls),
|
|
||||||
16, // # of connections in pool
|
|
||||||
);
|
|
||||||
|
|
||||||
let server = HttpServer::new(move || {
|
let server = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.data(pool.clone())
|
.data(pool.clone())
|
||||||
.service(web::resource("/users").route(web::post().to(add_user)))
|
.service(web::resource("/users").route(web::post().to(add_user)))
|
||||||
})
|
})
|
||||||
.bind(SERVER_ADDR)?
|
.bind(config.server_addr.clone())?
|
||||||
.run();
|
.run();
|
||||||
println!("Server running at http://{}/", SERVER_ADDR);
|
println!("Server running at http://{}/", config.server_addr);
|
||||||
|
|
||||||
server.await
|
server.await
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user