Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actix-web 4 support #36

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@

# env file
.env
.vscode/
2,598 changes: 1,329 additions & 1,269 deletions Cargo.lock

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
[package]
name = "conduit"
version = "0.1.0"
authors = ["grey <[email protected]>"]
edition = "2018"
authors = ["grey <[email protected]>", "thaddeus <[email protected]"]
edition = "2021"

[dependencies]
actix = "0.8.3"
actix-web = "1.0.7"
actix-cors = "0.1.0"
actix-service = "0.4.2"
actix-http = "0.2.10"
blob-uuid = "0.3.0"
actix = "0.13.0"
actix-rt = "2.7.0"
actix-web = "4.1.2"
actix-cors = "0.6.4"
actix-service = "2.0.2"
actix-http = "3.2.2"
blob-uuid = "0.5.0"
chrono = "0.4.6"
diesel = { version = "1.4.2", features = ["chrono", "postgres", "r2d2", "uuidv07", "serde_json"] }
dotenv = "0.14.1"
env_logger = "0.6.1"
diesel = { version = "2.0.2", features = ["chrono", "postgres", "r2d2", "uuid", "serde_json"] }
dotenv = "0.15.0"
env_logger = "0.9.3"
failure = "0.1.5"
futures = "0.1.25"
http = "0.1.16"
jsonwebtoken = "5.0.1"
futures = "0.3.25"
http = "0.2.8"
jsonwebtoken = "8.1.1"
lazy_static = "1.3.0"
libreauth = "0.11.0"
libreauth = "0.15.0"
log = "0.4.6"
num_cpus = "1.10.0"
regex = "1.1.6"
serde = "1.0.91"
serde_derive = "1.0.91"
serde_json = "1.0.39"
slug = "0.1.4"
uuid = { version = "0.7.4", features = ["serde", "v4"] }
validator = "0.8.0"
validator_derive = "0.8.0"
uuid = { version = "1.2", features = ["serde", "v4"] }
validator = { version = "0.16", features = ["derive"] }
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

> ### [Actix](https://actix.rs/) codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the [RealWorld](https://github.com/gothinkster/realworld) spec and API.

❗ (2021/05/13) This codebase is currently unmaintained, and I am not interested in maintaining it. This relies on an old version of Actix -- developers who want to learn Actix should probably read the latest docs at the [Actix website](https://actix.rs/).

This codebase was created to demonstrate a fully fledged fullstack application built with [Actix](https://actix.rs/) including CRUD operations, authentication, routing, pagination, and more. CORS, however, is not yet added.

This implementation is not reviewed. See the [Contributing](#contributing) section below.
Expand Down
103 changes: 44 additions & 59 deletions src/app/articles/comments.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use actix_web::{HttpRequest, HttpResponse, web::Json, web::Path, web::Data};
use actix_http::error::ResponseError;
use futures::{future::result, Future};
use actix_web::{web::Data, web::Json, web::Path, HttpRequest, HttpResponse};
use validator::Validate;

use super::super::AppState;
Expand Down Expand Up @@ -30,7 +28,7 @@ pub struct ArticleCommentPath {

#[derive(Debug, Validate, Deserialize)]
pub struct AddComment {
#[validate(length(min = "1", message = "fails validation - cannot be empty"))]
#[validate(length(min = 1, message = "fails validation - cannot be empty"))]
pub body: String,
}

Expand Down Expand Up @@ -78,72 +76,59 @@ pub struct CommentListResponse {

// Route handlers ↓

pub fn add(
pub async fn add(
state: Data<AppState>,
(path, form, req): (
Path<ArticlePath>,
Json<In<AddComment>>,
HttpRequest,
),
) -> impl Future<Item = HttpResponse, Error = Error> {
(path, form, req): (Path<ArticlePath>, Json<In<AddComment>>, HttpRequest),
) -> Result<HttpResponse, Error> {
let comment = form.into_inner().comment;

let db = state.db.clone();

result(comment.validate())
.from_err()
.and_then(move |_| authenticate(&state, &req))
.and_then(move |auth| {
db.send(AddCommentOuter {
auth,
slug: path.slug.to_owned(),
comment,
})
.from_err()
})
.and_then(|res| match res {
Ok(res) => Ok(HttpResponse::Ok().json(res)),
Err(e) => Ok(e.error_response()),
comment.validate()?;

let auth = authenticate(&state, &req).await?;
let res = state
.db
.send(AddCommentOuter {
auth,
slug: path.slug.to_owned(),
comment,
})
.await??;

Ok(HttpResponse::Ok().json(res))
}

pub fn list(
pub async fn list(
state: Data<AppState>,
(path, req): (Path<ArticlePath>, HttpRequest),
) -> impl Future<Item = HttpResponse, Error = Error> {
let db = state.db.clone();

authenticate(&state, &req)
.then(move |auth| {
db.send(GetComments {
auth: auth.ok(),
slug: path.slug.to_owned(),
})
.from_err()
})
.and_then(|res| match res {
Ok(res) => Ok(HttpResponse::Ok().json(res)),
Err(e) => Ok(e.error_response()),
) -> Result<HttpResponse, Error> {
let auth = authenticate(&state, &req)
.await
.map(|auth| Some(auth))
.unwrap_or(None);

let res = state
.db
.send(GetComments {
auth,
slug: path.slug.to_owned(),
})
.await??;

Ok(HttpResponse::Ok().json(res))
}

pub fn delete(
pub async fn delete(
state: Data<AppState>,
(path, req): (Path<ArticleCommentPath>, HttpRequest),
) -> impl Future<Item = HttpResponse, Error = Error> {
let db = state.db.clone();

authenticate(&state, &req)
.and_then(move |auth| {
db.send(DeleteComment {
auth,
slug: path.slug.to_owned(),
comment_id: path.comment_id.to_owned(),
})
.from_err()
})
.and_then(|res| match res {
Ok(_) => Ok(HttpResponse::Ok().finish()),
Err(e) => Ok(e.error_response()),
) -> Result<HttpResponse, Error> {
let auth = authenticate(&state, &req).await?;
let res = state
.db
.send(DeleteComment {
auth,
slug: path.slug.to_owned(),
comment_id: path.comment_id.to_owned(),
})
.await??;

Ok(HttpResponse::Ok().json(res))
}
Loading