5分钟APIG实战: 使用Rust语言快速构建API能力开放

序言:Rust语言简介

使用Rust进行HTTP Web后端应用开发

在Rust生态中进行HTTP Web后端应用开发目前主要依赖两个基础库:http 以及hyper,其中 http 提供HTTP标准相关的基础类型,如Request<T> 、Response<T>以及StatusCode和经常使用的Header等;hyper的定位是一个高效、准确的 HTTP底层库,它封装了HTTP的报文解析、报文编码处理、链接控制等内容,对于用户而言 只须要实现一个相似于Fn(Request) -> Response的映射,就能够完HTTP Web服务端的开 发。git

基于http以及hyper,社区中还有不少用于Web应用开发的框架,经常使用的有:github

值得一提的是上周刚发布的tower-web,由于这是官方net团队2018年工做计划的一部分, 这个库在将来会为Rust生态提供一个灵活、高效、易于使用的Web开发框架。那么事不宜迟, 咱们经过实战演练来一睹为快。web

 

在本月月底,tower-web将会集成到wrap项目中,成为wrap框架的一部分,开发的重心将会转移到wrap上。json

实战演练

登陆华为云,并建立弹性云服务器做为咱们的后端应用 服务器后端

实战中使用的系统版本为Ubuntu 16.04,若是选择不一样的系统须要根据状况调整命令。api

安装相关的工具链

apt update && apt install build-essential

# 安装Rust工具链
curl https://sh.rustup.rs -sSf | sh安全

这一步结束后,咱们就能够开始编写咱们的应用服务了。服务器

编写后端Web应用

此次分享咱们来构建一个RESTful中文分词API,首先咱们来建立一个Rust工程 cargo new --bin chinese_segmentationapp

接下来在Cargo.toml中添加相关依赖负载均衡

[dependencies]
tower-web = "0.2"

# Jieba Chinese Work Segmentation
jieba-rs = "0.2"

# logging utils
log = "0.4.0"
env_logger = "0.5.12"

# Serializing responses, deserializing requests
serde = "1.0.70"

而后是咱们的main.rs,与其余语言同样,在文件开始的部分引入外部依赖以及相关声明:

extern crate jieba_rs;
#[macro_use]
extern crate tower_web;

#[macro_use]
extern crate log;
extern crate env_logger;

use std::iter::FromIterator;
use std::collections::HashSet;

use jieba_rs::Jieba;
use tower_web::ServiceBuilder;

接下来咱们定义咱们的服务资源ChineseTokenizer:

#[derive(Debug)]
struct ChineseTokenizer {
    inner: Jieba,
}

impl ChineseTokenizer {
    pub fn new() -> ChineseTokenizer {
        ChineseTokenizer { inner: Jieba::new() }
    }

    // 对传入的字符串进行分词,并返回一个字符串向量
    pub fn cut(&self, text: &String) -> Vec<String> {
        let words = self.inner.cut(&text, true)
            .into_iter()
            .map(|word| word.to_owned())
            .collect::<HashSet<String>>();

        let mut words = Vec::from_iter(words.into_iter());

        // 因为使用HashSet进行去重会引入不肯定性,
        // 所以对结果进行重排,使输出的结果有序。
        words.sort();

        words
    }
}

定义了咱们的服务资源后,咱们来定义输入Web API的输入输出类型:

#[derive(Debug, Extract)]
struct TokenizeRequest {
    text: String
}

#[derive(Debug, Response)]
#[web(status = "200")] // 当 handler 返回 Ok(xx) 时,返回 200 状态码
struct TokenizeResponse {
    words: Vec<String>,
}

到目前为止,咱们已经有了咱们的服务资源,输入输出类型,接下来就到咱们的重头戏了, Web 部分的实现,别担忧,由于真的很简单。

impl_web! {
    impl ChineseTokenizer {
        #[post("/tokenize")]
        #[content_type("application/json")]
        fn tokenize(&self, body: TokenizeRequest) -> Reqult<TokenizeResponse, ()> {
            Ok(TokenizeResponse {
                words: self.cut(&body.text),
            })
        }
    }
}

最后是咱们的main函数:

fn main() {
    // 初始化Logger
    env_logger::init();
    let addr = "0.0.0.0:8081".parse().expect("invalid address");
    info!("listening on http://{}", addr);

    ServiceBuilder::new()
        .resource(ChineseTokenizer::new()) // 注册咱们的服务资源
        .run(&addr)                        // 让咱们的服务跑起来
        .unwrap();
}

如今,咱们经过命令RUST_LOG=chinese_segmentation=info cargo run --release来检验 一下咱们的成果了。服务在本地跑起来以后,咱们能够经过命令 curl -H "Content-Type: application/json" -X POST -d '{"text":"中间件小哥"}' <url> 来测试一下咱们的接口。

本地测试经过以后,就须要着手开始部署了,咱们检查一下弹性云服务器的安全组的入方向 是否放开8081端口。

API 部署

API 网关集成了监控、流控、负载均衡等一系列功能,为开发者提供高性能、高可用的API 托管服务,在本次实践中,咱们将咱们的API部署在API网关中。

登陆华为云API网关服务,选择“新建API”

 

  1. 填写API的基本信息

在本次实验中,选择无认证。

  1. 定义API请求

请求路径填为 /segment,方法为 POST

  1. 定义后端服务

请求方式设置为POST,在VPC通道这一项中,咱们须要新建VPC通道。端口设置为8081, 并将其与弹性云服务器关联。

 

 

建立完VPC通道后,回到API建立页面,填入相关信息:

 

 

网关建立完成后,咱们须要回到咱们的弹性云服务器,将咱们的后端服务器先跑起来:

RUST_LOG=chinese_segmentation=info nohup ./target/release/chinese_segmentation 2>&1 ~/api.log &

做为示例,这里使用nohup命令来跑咱们的服务。但在生产环境中,建议使用 systemd等工具来跑服务。

服务在云服务器运行起来以后,将API发布至RELEASE环境中。

而后咱们就能够和咱们的API愉快地玩耍啦。

相关文章
相关标签/搜索