# Rust-Lang의 웹 프레임워크 🚀Rocket

- Author: @baealex
- Published: 2020-04-12
- Updated: 2020-04-15
- Source: http://blex.me/@baealex/rust-lang-%EC%9B%B9-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-rocket
- Tags: 프로그래밍, 러스트

---

러스트로 웹 개발에 발을 담그려는데 러스트에 어떤 웹 프레임워크가 있으며 어떤 프레임워크를 선택할지 고민하는 글이다. 필자는 프레임워크 선택시 가장 중요하게 생각하는 부분은 프레임워크의 튜토리얼이다. 튜토리얼이 재밌는 글은 확실히 프레임워크가 어떤 부분에 중점을 맞췄는지 이해하기 쉽더라.

<br>

## Web Framework

러스트의 웹 프레임워크를 검색하여 다음의 프레임워크들을 발견할 수 있었다.

- [ACTIX](https://actix.rs) : 가장 빠름. 숙련자에게 추천되는 프레임워크. 서버 렌더링 지원. 깃허브 스타 7800개. 마지막 업데이트 2020년 04월.
- [Rocket](https://rocket.rs) : 입문자에게 추천되는 프레임워크. JSON응답 기본 제공. 서버 렌더링 지원. 깃허브 스타 9400개. 마지막 업데이트 2020년 03월.
- Nickel : 가벼움. 미들웨어로 확장할 수 있음. 서버 렌더링 지원. 깃허브 스타 2700개. 마지막 업데이트 2019년 10월.
- [Yew](https://yew.rs) : React에 영감얻음. WASM에 적합함. 컴포넌트 재사용 가능. 깃허브 스타 11200개. 마지막 업데이트 2020년 04월.

필자가 러스트에 관심을 가지게 된 이유는 `Nickel` 때문이었다. 웹 프레임워크 속도 비교에서 `Nickel`이 1등 자리에 있었는데 "이건 뭔데 이렇게 빠를까?"라는 생각으로 흥미를 가졌었다. 하지만 마지막 업데이트가 작년이라... 좀 신경쓰인다. `Yew`의 경우 웹 개발의 미래지향적 기술들만 사용되어 굉장히 매력적이라 생각된다. 차후에 꼭 다뤄봐야겠다. 우선 익숙한 웹 개발 환경으로 보이는 `ACTIX`와 `Rocket` 중에 선택하려 한다.

- https://rust.libhunt.com/compare-rocket-vs-nickel-rs

위 자료에서 로켓과 니켈의 비교가 이뤄지고 있는데 커뮤니티에선 `Rocket` 보다는 `ACTIX`를 추천한다. `Rocket`은 `REST` 아키텍처 혹은 초보자에게 적합하며 `ACTIX`는 `HTTP` 응용 프로그램에 가까운 프로젝트 혹은 숙련자에게 적합하다는 언급이 많으므로

![](https://static.blex.me/images/content/2020/3/20/cZoY3Xe72En4EMlWeyWD.jpg)

로켓으로 탑승하자!

<br>

## Rocket

처음 컴파일을 시도 했을 때 버전과 관련된 문제가 발생했다. 이에 대해 문서에 언급이 되어있는데

> Rocket은 Rust의 구문 확장과 기타 고급 불안정 기능을 사용하므로 Nightly 버전을 사용해야합니다.

```
rustup default nightly
```

위 명령어를 이용해 러스트를 `nightly` 버전으로 바꿔주자.

###### Terminal

```
cargo new hello-rocket --bin
cd hello-rocket
```

###### Cargo.toml

```
[dependencies]
rocket = "0.4.4"
```

###### main.rs

```rust
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}
```

`main.rs`를 위와 같은 내용으로 바꿔준뒤 `cargo run`를 입력하면

```
🚀 Rocket has launched from http://localhost:8000
```

위 문장을 볼 수 있다. 표시된 경로에 접속하면 `Hello World`라는 문장이 보여진다.

<br>

## Template

로켓에서 탬플릿을 사용하기 위해선 `Cargo.toml`에 아래 내용을 추가해 주어야한다. 로켓에선 기본 템플릿으로 `tera`라는 템플릿 엔진을 사용하고 있는데 `Django`의 템플릿 문법과 아주 유사하다.

###### Cargo.toml

```
[dependencies.rocket_contrib]
version = "0.4.4"
features = ["tera_templates"]
```

###### main.rs

```rust
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

extern crate rocket_contrib;
use rocket_contrib::templates::Template;

#[get("/")]
fn index() -> Template {
    let mut context = ();
    Template::render("index", &context)
}

fn main() {
    rocket::ignite()
        .mount("/", routes![index])
        .attach(Template::fairing())
        .launch();
}
```

이제 `templates`라는 디렉터리를 생성하여 그곳에 템플릿 파일일 삽입하자.

```
- src
  - main.rs
- templates
  - base.html.tera
  - index.html.tera
- Cargo.toml
```

###### base.html.tera

```html
<!doctype html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
        {% block body %}
        {% endblock body %}
    </body>
</html>
```

###### index.html.tera

```html
{% extends "base" %}

{% block body %}
    <h1>Hello, {{ name }}.</h1>
{% endblock body %}
```

장고 문법이랑 똑같다. 편ㅡ안. 현재 `index`에 `name`이라는 값을 전달하고 있는데 이 값 전달하는 것도 장고와 똑같다. 딕셔너리(해쉬맵) 형태로 전달해주면 된다.

###### main.rs

```rust
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

extern crate rocket_contrib;
use rocket_contrib::templates::Template;

use std::collections::HashMap;

#[get("/")]
fn index() -> Template {
    let mut context = HashMap::new();
    context.insert(
        "name".to_string(),
        "Jino Bae".to_string(),
    );
    Template::render("index", &context)
}

fn main() {
    rocket::ignite()
        .mount("/", routes![index])
        .attach(Template::fairing())
        .launch();
}
```

<br>

![](https://static.blex.me/images/content/2020/4/12/baealex/22_htqneo5kcGBzMAoBOiK2.png)

멋지게 결과가 출력되는 것을 볼 수 있다.
