[入門者必見] 初めてのRustでWEB上にHelloWorldを表示してみよう

## 目標
Hello Worldをweb上で表示しよう

## 理由
初心者がWebエンジニアとしての第一歩を踏み出そうとすると大抵最初でやる気をなくします。ネット上で調べたり、chatGPTに聞くと思いますが、わけのわからない単語や長めのコードが書いてあって何がどう処理されているかが分からないからです。単純なコードだけで良いのに、長めのコードが書いてあり訳が分からないことになりがちです。したがって、最もシンプルで最低限の知識で理解するようにHello Worldから始めましょう。入門者でもわかりやすくしました。

## 対象読者
- Rust初心者
- Web初心者
- vscode初心者

## 目次
- 完成品
- 環境構築
- vscode上でHello Worldをとりあえず表示してみる
- WEB上でHello Worldを表示するために最低限知るべきこと
- WEB上でHello World

### 完成品
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/5becea8f-551b-8725-2de1-97bc8ca85727.png)

### 環境構築
1. https://udemy.benesse.co.jp/development/system/rust.html
この記事のインストール部分を参考に環境構築をしておくと良い。
Rust入門2　Hello World!　以降の部分はvscode上で行うため読まなくても良いです

2. https://blog.senseshare.jp/vscode.html　
vscodeが入っていない人はこの記事を参考に入れておくと良いです。

3. vscode左側の拡張機能を押下してrustと入力してrustとrust-analyzerをインストールする(再読み込みが必要とでたら押す)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/9b1a32bb-e2a8-6c59-2eea-473d99e8603a.png)


### vscode上でHello Worldをとりあえず表示してみる
#### ここで覚えておくべき用語
- ターミナル
    - コンピューターをマウスではなくコマンドで操作できる
        - マウスでの操作より高度なことが出来る
            - rust専用のファイルを作成したりできる
        - cd コマンドは左クリックと同じ動作
        - code . コマンドはvscodeを立ち上げる
- cargo 
    - Rustの本来やるべき面倒なインストールやアップデート、プログラムの実行などが操作できるようにした便利なツール
        - cargo new ファイル名で　rustを実行するために必要なものが全部入ってたファイルが作成される
        - cargo run rustのファイルが実行できる


##### それでは下記の手順でvscode上でHello,World！を表示してみましょう。

1. デスクトップ上にフォルダーを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/abb5695b-1add-b4c8-410e-b589ee561424.png)

2. 右クリックでその他オプションを確認を左クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/ffa13b44-d3c6-2f38-0dfb-0fa2b7332ed7.png)

3. ターミナルで開く(T)を左クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/675a39ff-a620-9441-be79-4d5f70f61280.png)

4. 下記画面が出ることを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/0c477795-14db-fcde-f7ad-be1daea5ffcb.png)

5. cargo new hello　と入力しEnterボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/d2504a98-1b3e-8cb8-47fb-d59bdbda448c.png)

6. 下記みたいになることを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/90f323f8-2ce5-e247-bbf8-387b5e138e0f.png)

7. cd helloworldを入力してEnterボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/923e051e-1695-3a6a-63ad-78ac4ecf218f.png)


8. code . を入力してEnterボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/dc95f929-d271-7c8c-4536-e1775aeb1268.png)

9. vscodeが立ち上がることを確認し左側のHELLOWORLDを押下する(色が違うのはそういう設定をしているからです。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/0efbd376-1b1a-97b1-c46a-2f070628cea7.png)

10. srcを左クリックしてmain.rsを左クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/89c87354-0169-74f4-ed19-53d3910efb0c.png)

11. キーボードのCtlとShiftと@を同時押ししてvscode上のターミナルを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/b6558261-77ec-570d-9144-968cf6b5e94a.png)


12. cargo run と入力しEnter　Hello,Worldと出ることを確認する
実施するには　```Ctl+Shift+@```を押下して```cargo run ```で実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/8d1cb866-1036-56e1-97cb-049ae23a597f.png)


お疲れ様です。これでとりあえずは、Hello,Wold!が表示できましたね。

##### 次に解説に入ります。
```Rust
fn main(){
    println!("Hello world");
}
```



```fn main() { ... }```の部分は、プログラムが始まる場所を示しています。プログラムを実行すると、コンピューターは「main」という名前のこの部分から始めて、中に書かれている命令を一つ一つ実行していきます。main関数と呼びます。
他の関数も設定できます。


```println!```は「print line」の略で、「行を印刷する」という意味です。カッコの中にあるダブルクォーテーションマーク（" "）で囲まれた「Hello world」という文字が、実際に画面に表示される言葉ですね。

したがって、```fn main() { ... }の...```の部分が実行されるという意味ですね。少し難易度を上げましょう。下記の内容が分かりますか？

```Rust
fn hello() -> String{
    "Hello World".to_string()
}

fn main(){
    println!("{}",hello());
}
```

##### 解説に入ります
最初の関数は「hello」って名前がついているこの関数は、"Hello World"っていう言葉を返す。今回はString(文字列)で返していますね。```-> String```。「返す」っていうのは、関数が自分の仕事を終えたあとに、答えを持って戻ってくるっていう意味になります。
例えば、お母さんに「お皿を取ってきて」って頼まれたら、あなたはキッチンに行ってお皿を探します。そして、お皿を見つけたら、それを持ってお母さんのところに戻る。関数が値を返すのは、ちょうどそれと同じ感じです。

2番目の関数は「main」って名前ですね。これは、プログラムが始まるときに最初に動く特別な関数になります。

mainの中では、「println!」って書いてありますね。これは、何かを表示するための指示です。そして、{}って書いてあるところに、hello関数が返してくれる"Hello World"が入ります。

つまり疑似コードにすると
1. main関数でhello関数を呼び出している
2. hello関数では"Hello World"を返す

という処理が走ります。この処理はあとで使うので理解できるように
しておきましょう。


### WEB上でHello Worldを表示するために最低限知るべきこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/ba6c07a6-adc5-8f03-197d-5a08be9ccb09.png)

#### リクエストとは
- コンピューターが「これをください」って別のコンピューターにお願いすること。例えば、インターネットでウェブサイトを見たいときは、コンピューターがそのウェブサイトのコンピューターに「このページを見せてください」ってリクエストを送る

#### レスポンスとは
- リクエストを受け取ったコンピューターが「はい、どうぞ」って返事をすること。ウェブサイトの例でいうと、ウェブサイトのコンピューターが君のコンピューターに「はい、このページだよ」ってレスポンスを送り返す

※自分のパソコン内でコンピュータをクライント側とサーバー側に分けることもできる。特に設定しなければ最初から二つに分かれている。

#### リクエストには二種類ある
- GETとは
    - 「これをください」ってお願いするときに使うもの。例えば、ウェブサイトを見たいときは、GETリクエストを送る。URLの中には?○○=○○と書いてあるものがあるがこれはGETリクエストとなっている
```https://www.google.com/search?q=%E6%98%8E%E6%97%A5%E3%81%AE%E5%A4%A9%E6%B0%97```

- POSTとは
    - 「これを受け取ってください」ってお願いするときに使います。例えば、ユーザーがログインフォームに入力した情報を送信する場合は、POSTリクエストを使うのが適切。?○○=○○が無いので情報を渡さずに済む


#### IPアドレスとポート番号
- IPアドレスとは
    - ネット上の住所みたいなもの
- ポート番号とは
    - ネット上の部屋番号みたいなもの
- パス
    - /hoge/hugaみたいにサイト上で深く見ていくと付与されていくもの
- URL
    - IPアドレスとポート番号とパスを組み合わせて最初にhttpやhttpsを追加したもの


### WEB上でHello World
#### 要件
- WEB上でHello Worldと表示できる

#### 疑似コード(日本語でどのような手順で表示するかを考える)  
1. Hello World という文字列(""で囲まれたもの)を作成する
2. IPアドレスとポート番号を作成する
3. クライアントからサーバーにリクエストする
4. サーバーが受け取ったら処理をする
5. サーバーからクライアントに向けてページをレスポンスする
6. 表示される

#### 形にしていく


vscode上でmain.rsを開きましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/eeb0b15b-ff8f-fb80-af74-74080e05aa05.png)

```Rust
fn main() {
    println!("Hello, Rust!");
}
```

を下記のように書き換えてください。Errorが出ていると思いますが後で直します。
```Rust
use actix_web::{get,HttpResponse,HttpServer,Responder,App };
#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}
```

何となくわかりませんか？
そうです！これは　リクエストをGet形式で作成しており
Hello Worldという文字列を作成しているのです！！！

> use actix_web::{get,HttpResponse,HttpServer,Responder,App };

actix_webというライブラリから、get、HttpResponse、HttpServer、Responder、Appという機能を使うために、
このコードを書いています。
ライブラリは、プログラミングで使用できる便利な機能やツールの集まりです。
他の人が書いたコードを再利用することで、プログラムを素早く簡単に作ることができます。

> #[get("/")]

これは 何もURLに指定しないことを意味します。```https://-----```ということです。```#[get("/hoge")]```とすると```https://-----/hoge```
としないと読み込めないというわけです。

> async 

async キーワードはサーバーがリクエストを受け取った後、レスポンスを返すまでの間、他の処理を行えるということです。これによってサーバーのパフォーマンスが向上します。これを非同期関数と呼びます。

> fn hello() -> impl Responder 

hello関数を作って返す値は
Responderと言って、レスポンスできる形として返す関数となります。


>  HttpResponse::Ok().body("Hello world!")

getリクエストされたときにどういう処理をサーバーでするかを決めるのがここです。Hello Worldという文字を作成してレスポンスにしています。

HttpResponseは「HTTPレスポンス」と読みます。レスポンスととらえていただいて
問題ありません。

::Ok()は、コンピュータが「大丈夫だよ！」と言っているようなものです。これは、リクエストが正しく受理されたことを意味しています。

.body("Hello world!")は、コンピュータが実際に返事する内容を表しています。この場合、コンピュータは「Hello world!」というメッセージを送り返しています。


次にmain関数を設定します。えげつない見た目ですね。。

```Rust

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(hello)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
```



> #[actix_web::main]

main関数を非同期に実行できるようにするためのものですね。サーバーがリクエストを受け取った後、レスポンスを返すまでの間、他の処理を行えるということです。

> async fn main() -> std::io::Result<()> {

```->std::io::Result<()>```とはstd::io::Result<()>」は、入出力の操作が問題なく完了したら、特に何も返さないという意味になるんだよ。

もし入出力でエラーが起きたら、エラーの内容を返すことになるんだ。


> HttpServer::new(|| {App::new().service(hello)})

ここでサーバー側の処理を実施しています。具体的にはhello関数を呼び出していますね。あれ？さっきhello関数は処理したはずって思った方はいると思いますが、
違います。ここで実際に呼び出して始めて実行されているのです。

イメージとしては以下ですね。

HttpServer::new は、新しいお店を作ろうとしています。お店の名前は "HttpServer" です。

( と ) の間にある || は、お店の中で働く人を表しています。この人は、お客さんが来たときに、いつも同じ仕事をします。

{ と } の中が、その人の仕事の内容です。

App::new().service(hello) が、その人の仕事です。

App::new() は、お客さんを迎える準備をします。 service(hello) は、お客さんに "hello" というあいさつをします。

つまり、|| は、お店の中で働く人を表していて、その人はいつもお客さんに同じように "hello" とあいさつするんですね。

このように、|| は特別な役割を持っていて、HttpServer というお店の中で、お客さんに対する仕事を表しているんです。


> .bind(("127.0.0.1", 8080))?

URLを指定しますね。ここでリクエストを送る処理が走ります。
?は失敗するかしないかを自動で処理してくれます。

> .run().await

URLを指定されるまで実行を待機していますね。

完成品はこちらです。
まだエラーが出ていると思います。

```Rust
use actix_web::{get,HttpResponse,HttpServer,Responder,App };

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(hello)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}
```
最後にエラーをなくして実行しましょう。

まず```Cargo.toml```を開きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/9caa8a5b-898e-f29b-922e-42548354b299.png)

dependenciesに設定します。
```
[dependencies]
actix-web ="4.5.1"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/9d38e1fb-a37b-938e-4daa-1424e1505937.png)

actix_webというライブラりをインストールしているのですね。
ライブラリからツールを呼び出すのがuse actix_web::{get,HttpResponse,HttpServer,Responder,App };の部分。ライブラリを読み込むにはCargo.tomlに書きます。

実行しましょう！！

1. ```Ctl+Shift+@```を押します。
2. ```cargo run ```を入力して押下します。↓の感じがでたら成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/8348b7fb-00cf-ff98-bf69-e1defd15bc53.png)
3. GoogleでもFireFoxでもなんでもよいので、ブラウザを開いてください。
4. ```http://127.0.0.1:8080```をサイトに入力して下記のように出たら完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522968/75ab039d-06a4-2419-f365-4c12c6479082.png)


お疲れ様です！！
大変だったと思います。
最初の一歩目この記事からスタートしていただいたことうれしく思います。