プログラマー VTuber 衣亥栖ティオのちょっとした話

Youtubeに投稿したプログラミング学習動画の補足説明をするためのブログです。

プログラマーへの道 #147 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。 この記事はYouTubeに投稿した動画の補足ブログです。

投稿した動画

今回は以下の動画の補足説明をします。


GitHub のURL

私のGitHubは以下です。
https://github.com/tio-iis

Gist のURL

私のGitst(メモ書きみたいなもの)のURLは以下です。
https://gist.github.com/tio-iis

今回の動画で実装したソースコード

今回の実装は以下です。
https://github.com/tio-iis/memo-server/pull/60/files

現時点でのソースコードは以下です。
https://github.com/tio-iis/memo-server/tree/0f0ae0d26d94490991d2730f0b288b205bec8dc1

補足内容

favicon.ico について

favicon についての説明は以下です。
https://wa3.i-3-i.info/word14169.html

動画内でも言及した通り、faviconというのはブラウザのタブに表示されるアイコン画像のことです。 これは通常ブラウザが自動的にバックエンドサーバから取得します。 デフォルトの取得先URLは "/favicon.ico" のようですね。

(今回は用意していませんが)メモ帳アプリのバックエンドサーバが http://localhost:8080/favicon.ico でアイコン画像を表示するように実装すれば、 ブラウザのタブにその画像が表示されることになります。

ブラウザのfavicon取得先は以下のように変更することもできます。
https://glatchdesign.com/blog/settings-favicon/

プログラマーへの道 #146 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。 この記事はYouTubeに投稿した動画の補足ブログです。

投稿した動画

今回は以下の動画の補足説明をします。


GitHub のURL

私のGitHubは以下です。
https://github.com/tio-iis

Gist のURL

私のGitst(メモ書きみたいなもの)のURLは以下です。
https://gist.github.com/tio-iis

今回の動画で実装したソースコード

今回の実装は以下です。
https://github.com/tio-iis/memo-server/pull/59/files

現時点でのソースコードは以下です。
https://github.com/tio-iis/memo-server/tree/0fe14309209e98f744ad946c7310ce3a2d414e42

補足内容

Content-Type について

Content-Type についての説明は以下です。
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Type

Content-Type はHTTPリクエストのHeaderとHTTPレスポンスのHeaderに付けることができます。 HTTPリクエストの場合はリクエストを送信するクライアント側がサーバに送信するデータフォーマットを伝えるために利用します。 HTTPレスポンスの場合はレスポンスを返すサーバがクライアント側に返すデータフォーマットを伝えるために利用します。

今回の実装はバックエンドサーバのバリデーション実装ということなので、HTTPリクエストのContent-Typeをバリデーションしていますが、 本来であればHTTPレスポンスにもContent-Typeを付けるべきですね。 こちらは今後の動画で対応する予定です。

プログラマーへの道 #145 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。 この記事はYouTubeに投稿した動画の補足ブログです。

投稿した動画

今回は以下の動画の補足説明をします。


GitHub のURL

私のGitHubは以下です。
https://github.com/tio-iis

Gist のURL

私のGitst(メモ書きみたいなもの)のURLは以下です。
https://gist.github.com/tio-iis

今回の動画で実装したソースコード

今回の実装は以下です。
https://github.com/tio-iis/memo-server/pull/58/files

現時点でのソースコードは以下です。
https://github.com/tio-iis/memo-server/tree/725ecd28e75bbc21623343f3532bd55b642e43ed

補足内容

HTTP Method の PUT について

HTTP Method の PUT の説明は以下です。
https://developer.mozilla.org/ja/docs/Web/HTTP/Methods/PUT

PUT は「データがなかったら作成する。データがあったら更新する。」という挙動をするメソッドなので、 データの登録と更新を合わせ持った HTTP Method ということになります。 しかし、メモ帳アプリのメモ更新エンドポイントでは「データがなかったら作成する」という挙動は実装していません。 理由としては、学習動画の都合上こういった実装にしているということになります。 この問題点は今後の動画で改修する予定なので、それはまでは "PUT = 更新に利用する" という認識で良いと思います。

IDの重複バリデーションについて

動画でも言及した通り、悪意のある人が curl で直接メモ帳サーバにアクセスしてくる可能性もあるので、 バリデーションはしっかりと実施する必要があります。

プログラマーへの道 #144 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。 この記事はYouTubeに投稿した動画の補足ブログです。

投稿した動画

今回は以下の動画の補足説明をします。


GitHub のURL

私のGitHubは以下です。
https://github.com/tio-iis

Gist のURL

私のGitst(メモ書きみたいなもの)のURLは以下です。
https://gist.github.com/tio-iis

今回の動画で実装したソースコード

今回の実装は以下です。
https://github.com/tio-iis/memo-server/pull/57/files

現時点でのソースコードは以下です。
https://github.com/tio-iis/memo-server/tree/076ce8982afa4e56a5c5987c317e50fb0246eaed

補足内容

メモのタイトルが同じでも更新できるケースについて

メモ帳アプリには「メモのタイトルが重複してはいけない」という仕様があります。 しかし、更新対象のメモのタイトルは同じものを指定することができます。 そのケースをバリデーションで除外しているのが以下のコードです。
https://github.com/tio-iis/memo-server/pull/57/files#diff-2873f79a86c0d8b3335cd7731b0ecf7dd4301eb19a82ef7a1cba7589b5252261R207-R210

更新エンドポイントを新規実装した件について

動画内でも言及していますが、今までは /add_memo というエンドポイントでメモの登録と更新をしていましたが、 今回は更新専用のエンドポイントを実装しています。

更新専用のエンドポイントを実装した理由は以下です。

  • 一般的に登録と更新のエンドポイントは分かれている。
  • 登録と更新では細かい実装が異なるので、共通化することができない。
  • add_memo というエンドポイントで更新もできるというのが分かりづらい。

3つ挙げていますが、実は今回のメモ帳アプリ程度の簡単な仕様であれば、メモの登録と更新を1つのエンドポイントで実装することも可能です。 ただ、業務では分けて実装するのが一般的なので、今回も分けています。

プログラマーへの道 #143 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。 この記事はYouTubeに投稿した動画の補足ブログです。

投稿した動画

今回は以下の動画の補足説明をします。


GitHub のURL

私のGitHubは以下です。
https://github.com/tio-iis

Gist のURL

私のGitst(メモ書きみたいなもの)のURLは以下です。
https://gist.github.com/tio-iis

今回の動画で実装したソースコード

今回の実装は以下です。
https://github.com/tio-iis/memo-server/pull/56/files

現時点でのソースコードは以下です。
https://github.com/tio-iis/memo-server/tree/ebcee412058f7beea1e97431e3028e72f08d9353

補足内容

Goにおけるスライスの特定要素の削除について

Goにはスライスの特定の様子を削除する機能が存在しないので、以下な実装をする必要があります。
https://stackoverflow.com/questions/37334119/how-to-delete-an-element-from-a-slice-in-golang

今回の動画の削除実装も上記の記事を参考にしたものです。

Goのスライスの範囲指定

Goではコロンを利用して特定の範囲の要素を取得することができます。 今回のスライスの削除実装でも利用しています。
https://code-graffiti.com/slice-in-golang/#toc2

プログラマーへの道 #142 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。 この記事はYouTubeに投稿した動画の補足ブログです。

投稿した動画

今回は以下の動画の補足説明をします。


GitHub のURL

私のGitHubは以下です。
https://github.com/tio-iis

Gist のURL

私のGitst(メモ書きみたいなもの)のURLは以下です。
https://gist.github.com/tio-iis

今回の動画で実装したソースコード

今回の実装は以下です。
https://github.com/tio-iis/memo-server/pull/55/files

現時点でのソースコードは以下です。
https://github.com/tio-iis/memo-server/tree/657268ec2ede1dd14d283c775e65b68f77270b1e

補足内容

Goにおけるスライスの特定要素の削除について

Goにはスライスの特定の要素を削除するという仕組みが用意されていないので、 動画内で実装したように少し面倒な実装をする必要があります。 実装自体は次回の動画で説明するので現時点では理解できなくて問題ないです。

次回の動画の前に予習したい方は以下のURLが役立つと思います。
https://stackoverflow.com/questions/37334119/how-to-delete-an-element-from-a-slice-in-golang

ちなみにmapはキーを指定した削除ができます。
https://golang.hateblo.jp/entry/2019/10/07/202140#%E5%89%8A%E9%99%A4

プログラマーへの道 #141 の補足説明

こんにちは、プログラマーVTuberの衣亥栖ティオです。 この記事はYouTubeに投稿した動画の補足ブログです。

投稿した動画

今回は以下の動画の補足説明をします。


GitHub のURL

私のGitHubは以下です。
https://github.com/tio-iis

Gist のURL

私のGitst(メモ書きみたいなもの)のURLは以下です。
https://gist.github.com/tio-iis

今回の動画で実装したソースコード

今回の実装は以下です。
https://github.com/tio-iis/memo-server/pull/54/files

現時点でのソースコードは以下です。
https://github.com/tio-iis/memo-server/tree/1fb393027f70eb77721d036267bcec77bf6e224c

補足内容

バリデーション時に警告ログを出力している件について

前回のブログでも言及した通り、警告ログの出力を修正しました。
https://github.com/tio-iis/memo-server/pull/54/files#diff-2873f79a86c0d8b3335cd7731b0ecf7dd4301eb19a82ef7a1cba7589b5252261R132

同じミスをしないように以下のようにコメントを残しています。
https://github.com/tio-iis/memo-server/pull/54/files#diff-2873f79a86c0d8b3335cd7731b0ecf7dd4301eb19a82ef7a1cba7589b5252261R222-R223

fmt.Sprintf() によるエラーメッセージの出力について

動画では以下のエラーメッセージ出力が上手くいきませんでした。
https://github.com/tio-iis/memo-server/pull/54/files#diff-2873f79a86c0d8b3335cd7731b0ecf7dd4301eb19a82ef7a1cba7589b5252261L221

具体的には以下のようなエラーメッセージが出力されてしまいました。 本当は error の値にエラーメッセージを出力したかったのですが、[0xc0000b82a0] という値になっています。 これはスライスのポインタです。

{"date_time":"2022-06-19 05:15:22","level":"WARNING","kind":"log","message":"invalid memo, error = [0xc0000b82a0]"}

エラーメッセージを出力するにはどうすればいいかというと、方法としては3つあります。

1つ目は動画内でも実施した通り、for でスライスの値を取り出すという方法です。これはシンプルな方法ですが、少し面倒ですね。

2つ目はスライスにしている構造体をポインタではなく、値にするという方法です。これは *ErrorMessage を ErrorMessage に変更するということです。 アスタリスクをなくすことで、ErrorMessageのポインタではなく、ErrorMessageの値を保持するスライスに変更することになります。 これは一見良さそうですが、動画の方針として"構造体はポインタで扱う"というものがあるので、ここだけ例外にすると混乱しそうだったので、避けました。 しかし、そもそも"エラーメッセージを出力するために構造体をポインタで扱わないようにする"というのは実装の方針としてはおかしいことなので、 どちらにしろポインタを値に変更するというのは却下しました。

3つ目はスライスにStringerインターフェースを実装するという方法です。実はこれがエラーメッセージを表示させるための正攻法になります。 しかし、現時点でインターフェースやStringerという概念を扱っていないので、今回の動画でこれを説明するのは難しかったです。

最終的には"警告ログはバリデーション時に出力する"という方針に気づいたので、 エラーメッセージの表示に悩むことはなくなりましたが、 構造体のポインタのスライスの値を表示するのは、毎回面倒だなーと思ってしまいますね。

参考にしたURLは以下です。
https://stackoverflow.com/questions/24489384/how-to-print-the-values-of-slices