use maglev::HttpError;
#[derive(Debug, thiserror::Error, HttpError)]
pub enum Error {
#[error("post {0} not found")]
#[http_error(NOT_FOUND, "post not found")]
NotFound(Uuid),
#[error("auth: {0}")]
#[http_error(UNAUTHORIZED, "unauthorized")]
Auth(#[from] maglev::auth::AuthError),
#[error("db: {0}")]
#[http_error(INTERNAL_SERVER_ERROR)]
Sqlx(#[from] sqlx::Error),
}
use maglev::auth::{AuthError, Jwt};
use maglev::auth::ClaimsExtractor;
pub struct Author { pub id: Uuid }
impl<S: Send + Sync> ClaimsExtractor<S>
for Author {
type Claims = Claims;
type Rejection = AuthError;
async fn try_extract(c: Claims, _: &S)
-> Result<Self, AuthError> {
Ok(Author { id: c.sub })
}
}
// Any handler can now ask for the author:
async fn me(me: Jwt<Author>) -> Json<Author>
async fn create_post(
author: Jwt<Author>,
State(db): State<PgPool>,
Json(new): Json<NewPost>,
) -> Result<Json<Post>, Error> {
let post = sqlx::query_as!(
Post,
"INSERT INTO posts
(author_id, title, body)
VALUES ($1, $2, $3)
RETURNING *",
author.id, new.title, new.body
)
.fetch_one(&db)
.await?;
Ok(Json(post))
}
let jwt = JwtConfig::new(&config.hmac_key)
.duration(Duration::minutes(30))
.build();
let registry = JobRegistry::new()
.register::<PublishScheduledPosts>();
Worker::new(queue, registry, ctx.clone())
.concurrency(2)
.start();
let app = Router::new()
.route("/posts", post(create_post))
.with_state(ctx);
maglev::serve(([0, 0, 0, 0], 8080), app)
.await?;