内容介绍
本专题将带你使用 axum 构建一个短链接服务。短链接,又称短网址,是指将一个可能比较长的链接变成固定长度的短链接,便于在社交媒体、短信等渠道发布。另外,它也可以隐藏原链接里的一些敏感信息,比如带邀请码的推广链接。短链接的核心算法
本章将对短链接的原理及实现算法进行讲解。准备工作
搞定了短链接的核心算法,我们可以开始进行业务开发。本章将进行一系列的准备工作,包括:配置、日志、自定义错误、handler、数据库操作原型、模板等。创建短链接
本章将实现创建短链接功能。短链接跳转到原始链接
我们继续实现功能,本章要实现的是通过短链接跳转到原始链接的功能。注意,跳转之前,我们需要将它的访问量加一。排行榜
本章继续完善短链接服务:显示排行。总结与代码清理
目前为止,我们的短链接服务基本已经完成了。但有一些地方不完善,同时有些警告没有处理掉。
总结与代码清理
- 896671
- 2021-11-25 20:40:50
目前为止,我们的短链接服务基本已经完成了。但有一些地方不完善,同时有些警告没有处理掉。
本章代码在06/清理分支。
本章代码在06/清理分支。
AppError
的处理
因为我们的 MsgTemplate
已经提供了 err()
方法,所以在 AppError
可以直接调用该方法:
let tmpl = MsgTemplate::err(msg.clone());
let html = tmpl.render().unwrap_or(msg);
Html(html).into_response()
另外,为了处理保留字的检测,我们还要加上:
pub fn reserved_word(word: &str) -> Self {
let msg = format!("{}是保留字", word);
Self::from_str(&msg, AppErrorType::ReservedWord)
}
AppErrorType
的处理
当然,AppErrorType
也要加上保留字的枚举项:
pub enum AppErrorType {
//...
ReservedWord,
}
将 MsgTemplate::ok()
方法删除,因为没有任何地方用到它。
为了便于显示添加成功的短链接,我们将index_action()
的跳转改为 index()
index_action()
let redirect_url = format!("/?id={}", result.id);
Ok(redirect(&redirect_url))
另外,为了检测生成的短链接是否是保留字(虽然概率极小,在开启自定义短链接时,这个检测非常有必要),我们还需要增加:
if (&state).short_url_cfg.in_reserved_words(&id) {
return Err(AppError::reserved_word(&id));
};
index()
#[derive(Deserialize)]
pub struct IndexArgs {
pub id: Option<String>,
}
pub async fn index(
Extension(state): Extension<AppState>,
Query(args): Query<IndexArgs>,
) -> HandlerHtmlResult {
let handler_name = "index";
let tmpl = IndexTemplate {
id: args.id.clone(),
short_url_domain: state.short_url_cfg.domain.clone(),
};
render(tmpl).map_err(log_error(handler_name.to_string()))
}
模板结构体
对应的,IndexTemplate
也要进行处理:
#[derive(Template)]
#[template(path = "index.html")]
pub struct IndexTemplate {
pub id: Option<String>,
pub short_url_domain: String,
}
impl IndexTemplate {
pub fn id(&self) -> String {
self.id.clone().unwrap_or("".to_string())
}
}
模板文件
<h1>创建你的短网址</h1>
{%if !self.id().is_empty() %}
<div class="alert alert-info my-3">
短链接创建成功:<a href="//{{short_url_domain}}/{{self.id()}}" target="_blank"
>{{short_url_domain}}/{{self.id()}}</a
>
</div>
{% endif%}
<form action="/" method="post" autocomplete="off"></form>
核心算法的处理
把两个带_with_seed
后缀的函数加上 #[allow(unused)]
数据库的处理
本专题带你实现了一个短链接服务。
-
短链接算法:使用 murmur3 将原始链接转成 32 位的正整数哈希值,然后将这个哈希值转成字符形式的 base62, 这个就是我们的短链接
-
模板:本专题使用了模板引擎
-
PostgreSQL:当然,本专题少不了数据库
-
静态资源:为了配合模板引用的静态文件,我们加上了静态资源的处理
-
配置文件、日志:这两个“标配”自然少不了
短链接算法:使用 murmur3 将原始链接转成 32 位的正整数哈希值,然后将这个哈希值转成字符形式的 base62, 这个就是我们的短链接
模板:本专题使用了模板引擎
PostgreSQL:当然,本专题少不了数据库
静态资源:为了配合模板引用的静态文件,我们加上了静态资源的处理
配置文件、日志:这两个“标配”自然少不了