21个版本 (5个破坏性更新)
| 0.6.0 | 2022年11月29日 |
|---|---|
| 0.5.2 | 2022年11月16日 |
| 0.4.1 | 2022年8月24日 |
| 0.3.2 | 2022年8月5日 |
| 0.1.4 | 2022年3月25日 |
#836 in HTTP服务器
每月92次下载
在 2 crates 中使用
69KB
1.5K SLoC
Resp Result
Web框架响应的帮助数据结构
为什么
- 当使用
Result作为Web框架响应类型时,当Err(_)时,通常不会是预期的500错误 - 使用非Result类型作为Web框架响应类型时,不能使用
?,代码将充满if let或match
这就是为什么我需要一个 RespResult 的原因,它可以
- 当它变成
RespResult::Err时,控制响应代码或其他消息,而不仅仅是500 - 实现
Try,因此可以使用友好的?来简化代码
注意:因为
Try尚未稳定,这个crate需要Nightlyrust
用法
安装
将 resp-result 添加到您的crate
[dependencies]
resp-result = "*"
功能标志
-
for-axum:启用 axum 支持,这将实现IntoResponse用于RespResult -
extra-error:在特性RespError中启用额外错误消息 -
tracing:启用使用 tracing 的记录器 -
axum-full:等于for-axum+extra-error -
actix-full:等于for-actix+extra-error -
nightly_try_v2:为RespResult实现Try,使其可以使用?,这将启用功能 try_trait_v2 并需要 Nightly rust 编译器
定义一个错误
RespResult<T,E> 要求 E 实现 RespError
例如
use resp_result::{RespError, RespResult};
use std::borrow::Cow;
use http::StatusCode;
pub struct PlainError(String);
impl RespError for PlainError{
fn log_message(&self) -> Cow<'_, str> {
Cow::Owned(format!("PlainError: {}", self.0))
}
fn resp_message(&self) -> Cow<'_, str> {
"PlainError".into()
}
fn http_code(&self) -> StatusCode {
StatusCode::BAD_REQUEST
}
type ExtraMessage = String;
fn extra_message(&self) -> Self::ExtraMessage {
self.0.clone()
}
}
/// this can be use as handler return type
type PlainRResult<T> = RespResult<T, PlainError>;
RespResult<T, E> 中 T 的边界
T 需要实现 Serialize 并具有 'static 生命周期
使用它
以下是一个使用 RespResult 的示例
use resp_result::{RespError, RespResult};
use std::borrow::Cow;
use http::StatusCode;
pub struct PlainError(String);
impl RespError for PlainError{
fn log_message(&self) -> Cow<'_, str> {
Cow::Owned(format!("PlainError: {}", self.0))
}
type ExtraMessage = String;
fn extra_message(&self) -> Self::ExtraMessage {
self.0.clone()
}
}
/// this can be use as handler return type
type PlainRResult<T> = RespResult<T, PlainError>;
pub async fn welcome_short_name(name: String) -> PlainRResult<String>{
if name.len() >= 8{
// you can using `?` just like the function that return `Result`
Err(PlainError("the name size great then 8".to_string()))?;
}
if name.len() >= 4 {
// `Result::Ok` can convert into `RespResult::Success` just using `into`
Ok(format!("welcome! {name} with size great then 4")).into()
}else{
// or just direct using `RespResult::ok`
RespResult::ok(format!("welcome! {name}"))
}
}
ExtraFlag 和 ExtraFlags
一般来说,RespResult::Success 总是生成状态码为 200 OK 的响应,并使用 serde_json 将正文序列化为 JSON。但有时我们希望返回一个 304 Not Modified 响应,正文为空,以告知客户端资源没有变化。为了支持上述使用情况,出现了 ExtraFlag 和 ExtraFlags
Extra Flag
额外的标志有 4 种不同的类型,可以对响应产生不同的影响
empty_body:此标志将阻止RespResult执行序列化到响应正文status:此标志将覆盖响应的StatusCodeset-header:此标志将提供或附加到响应头映射中remove-header:此标志将从响应头映射中删除头
不同的额外标志可以使用 + 组合效果或使用 += 添加效果
Extra Flags
额外的标志是一组额外的标志
FlagWrap
标志包装提供发送额外标志的包装器
在使用额外标志时,需要将返回类型从 RespResult<T, E> 更改为 RespResult<FlagWrap<T>, E>
以下示例将状态码更改为 404 Not Found
use resp_result::{RespError, RespResult, FlagWrap, ExtraFlag};
use std::borrow::Cow;
use http::StatusCode;
pub struct PlainError(String);
impl RespError for PlainError{
fn log_message(&self) -> Cow<'_, str> {
Cow::Owned(format!("PlainError: {}", self.0))
}
type ExtraMessage = String;
fn extra_message(&self) -> Self::ExtraMessage {
self.0.clone()
}
}
/// this can be use as handler return type
type PlainRResult<T> = RespResult<T, PlainError>;
pub async fn welcome_short_name(
name: String,
) -> PlainRResult<FlagWrap<String>>{
if name.len() >= 8{
RespResult::ok(
format!("welcome! {name} your name size is {}",name.len()))
// using `with_flags` to covert RespResult<T, E>
// to `RespResult<FlagWrap<T>, E>`
// using `()` for no extra flags
.with_flags(())
}else{
// suing `flag_ok` direct construct a flag with resp result
RespResult::flag_ok(
format!("Welcome! {name}"),
ExtraFlag::status(StatusCode::NOT_FOUND)
)
}
}
影响 RespResult 的行为
默认情况下,RespResult 将按如下方式序列化响应体:
{
"is-ok": true,
"error-message": "...",
"extra-msg": "...",
"body": null
}
可以通过使用 set_config 来设置全局配置以更改默认行为。
例如,通过配置,我们可以将响应体更改如下:
{
"status": "fail",
"reterror": 10001,
"message": "something wrong",
"body": null
}
依赖项
~2-14MB
~177K SLoC