4个版本 (2个重大更新)
0.3.1 | 2019年5月8日 |
---|---|
0.3.0 | 2019年4月12日 |
0.2.0 | 2019年4月11日 |
0.1.0 | 2019年4月10日 |
#9 in #HTTP POST
24KB
196 行
报告API和网络错误记录
此crate提供了一些有用的Rust代码,用于处理W3C的《报告API》和《网络错误记录》草案规范。
[dependencies]
reporting-api = "^0.3"
概述
报告API的核心非常简单:通过POST请求将报告上传到您选择的URL。POST请求的有效负载是一个JSON编码的报告数组,报告模式由规范定义。
报告API可以用于上传许多不同类型的报告。例如,报告本身定义了来自浏览器中运行的JavaScript环境的崩溃报告、弃用和干预。其他报告类型可能相当复杂,需要在自己的规范中定义,例如网络错误记录和内容安全策略。无论它们在哪里定义,每种报告类型都定义了一些特定于该类型的字段(即主体),报告API定义了一些所有类型都通用的字段。
此库提供所有这些架构的正则Rust类型定义,以及使用serde进行序列化和反序列化的能力。我们仔细定义了一切,以便serde_json会自动做正确的事情,并使用与各种规范一致的JSON序列化。我们还提供了一种定义新报告类型主体架构的方法,并使它们无缝地与序列化逻辑的其他部分集成。
收集报告
如果您只想从某个地方接收报告(例如,您正在实现一个收集器,而我们已经为所有您关心的报告类型定义了Rust类型),那么使用此库的最简单方法就是使用它。
要实现这一点,你只需使用serde_json
来反序列化你收到的JSON字符串的内容即可。
let reports: Vec<BareReport> = serde_json::from_str(payload).unwrap();
就是这样!向量中的元素将代表这次上传批次中的每个报告。每个都是一个“裸”报告,这意味着我们没有试图确定报告的类型,或者哪个Rust类型与该报告类型相对应。相反,报告的原始正文(在body
字段中)作为serde_json
的Value
。
如果你知道你想要处理哪种特定的报告类型,你可以使用裸报告的parse
方法将其转换为“解析”后的报告。例如,如果你只关心网络错误记录报告。
// Ignore both kinds of failure, returning a Vec<Report<NEL>>.
let nel_reports = reports
.into_iter()
.filter_map(BareReport::parse::<NEL>)
.filter_map(Result::ok)
.collect::<Vec<Report<NEL>>>();
请注意,parse
的返回值被包装在两者Option
和两者Result
中。外层的Option
告诉你报告是否为预期的类型。如果是,则内层的Result
告诉你我们是否能够根据该类型预期的模式解析报告的body
字段。在这个例子中,因此我们需要两次filter_map
调用以去除任何不匹配和错误,从而留下一个Report<NEL>
实例的向量。
创建一个新的报告类型
这种情况应该相对罕见,但考虑一个使用Reporting API但在这里没有涉及的新报告类型。例如,假设有一个新的lint
报告类型,其正文内容如下:
{
"source_file": "foo.js",
"line": 10,
"column": 12,
"finding": "Indentation doesn't match the rest of the file"
}
首先,你需要定义一个Rust类型来保存正文内容。
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Lint {
pub source_file: String,
pub line: u32,
pub column: u32,
pub finding: String,
}
最后,你必须为你的新类型实现ReportType
特理,该特理定义了报告负载中type
字段的新报告类型的值。
impl ReportType for Lint {
fn report_type() -> &'static str {
"lint"
}
}
就这样!现在parse
方法将支持你的新报告类型。
依赖项
~0.6–1.4MB
~32K SLoC