Sakiのプログラミング学習ブログ

プログラミングについて学んだことや、学習の振返りを書いています。

週報 2/22(月)~2/28(日)

2/22(月)~2/28(日)の一週間の学習の振り返りをざっくり。

今週の目標&結果

今週の目標 結果
TwitterのDB設計をどうやって行ったかまとめる 日報に詳細書いてあるので、やめた
DB設計:他の受講生の提出物をチェック
自己参照/自己結合の理解
【ブログ】DB設計で学んだこと&詰まった点
【ブログ】web技術の基本で学んだこと
【ブログ】webを支える技術で学んだこと
【ブログ】URL設計について学んだこと
【ブログ】Gitで課題提出するまでの手順
【ブログ】TeamGeekを輪読会の感想 着手もできず
2月の振り返り&計画の見直し
(できれば)Railsの教科書の6~8章(最後) 6と8は完了/
残り7章
(できれば)book_appをリモートリポジトリのmainブランチにpushする

今週の学習時間

ラクティス外の学習・勉強会への参加は含めない。

日付 目標 実際
2/22(月) 2:00 0:00
2/23(火)祝日 6:00 0:45
2/24(水) 2:00 2:00
2/25(木)休み 6:00 4:15
2/26(金) 2:00 0:00
2/27(土) 6:00 7:30
2/28(日) 6:00 8:15
合計 30:00 22:45

今週やったこと

2/22(月

やったこと

  • 学習せず。

考えたこと

  • 入浴した後、自室で学習していたのだが、眠すぎて週報を書くことすらできなかった。お風呂に入ると体が一気に睡眠モードになってしまう😴
  • 復習が疎かになっているので、Railsに本格的に入る前に、今週はDB設計,RESTの復習に注力する予定。

2/23(火)祝日

やったこと

考えたこと

  • 週報を書いた後、復習をかねてブログを書こうとしたら、少し疲れていてなかなか集中できず、せっかくコワーキングスペースに行ったのに帰ってしまった。
    いつもはコワーキングスペースに行くとスッと集中モードに入れるので、うまく睡眠が取れなかったのかなと思った。

2/24(水)

やったこと

  • Railsの教科書(5~6,8章)
    • 5章(p.91-95):scaffoldで作った既存のテーブルに、あとからカラムを追加する
    • 6章:awesome_printをインストールしたが使えず。どうやらRubyのバージョンが原因のよう。bundlerの理解を深めた。
    • 8章:あとがき

考えたこと

  • 5-6章,8章を読み終わった!残るは7章!
  • Ruby3.0.0でawesome_printが使えない問題は、バージョン1.9.0で解決されている。時間があるときに試す。
  • bundlerの仕組みがよく分からずモヤモヤしていたが、「Bundlerは、GemfileとGemfile.lockで互換性の管理をしつつ、bundle updateで新しいバージョンもインストールして使えるから、便利だよ!」ということが分かった💡Ruby超入門10-1にも記述があるので、読み返す。

2/25(木)

やったこと

考えたこと

  • DB設計は、色んなところで理解につまづき、世界観?を理解するのが難しかったので、これから学ぶ方の助けになればいいなという気持ちで書いた。
  • Gitの記事は、フィヨルド生で参考になったと仰ってくださる方がいて嬉しかった!

2/26(金)

やったこと

  • 学習せず。

考えたこと

  • 早起きに失敗して出勤前に学習できず&仕事後疲れて学習できなかった。

2/27(土)

やったこと

考えたこと

  • ずっと後回しにしていた、去年秋に読み終わった『Web技術の基本』を読んで学んだこと・疑問に思って調べたこと・感想を書けた。
  • ブログが思ったより、書くのに時間がかかった💦久々に本の内容を復習して、それを自分なりに言葉で説明してまとめたので、良い復習になった。
  • 伊藤さんの記事:ブログに技術書の内容を丸写しする問題点と、オリジナルなコンテンツを書くためのアイデアを参考にしながら、記事の内容が無断転載にならないように、気をつけて書いたが、大丈夫か少し心配😅もしご指摘があったらすぐに修正or削除するつもり。

2/28(日)

やったこと

考えたこと

  • ずっと書こうと思って後回しにしていた記事を2本も書けた!

今週の振り返り

✅ できたこと/できるようになったこと

  • 今週はブログでたくさんアウトプットできた!週報をのぞいて記事5本書いた。がんばった〜💪
  • 気づけば今年から始めた週報を2ヶ月連続で書けている。書かないと気持ち悪くなるくらい習慣化できている✨
  • 最近休みの日は無理やり早起きせず、ぐっすり眠ることを重視している。アラームも休みの日はつけないことにした。
    無理やり早起きしても後でエネルギー切れを起こしてしまうので、8時台まで寝るのは許容範囲にしている。

✅ "こうしたらもっと良かった"と思うこと

  • 火曜の祝日にもう少し学習できたらよかったな〜と思う。でも、毎日元気全開で学習するのは難しいので、反省はしても責めないようにする。 やる気と健康にはムラがあるもの!

来週の目標

合計23:00分

  • WebアプリからのDB利用(5:00) ※レビューに時間かかるので最優先
    • 残り:prepared statementを使った実装。
    • GitHubへプルリクエストで提出
    • 合格したい!
  • Railsの教科書の7章(1:30)
  • Railsi18n を理解する (9:30)
  • kaminari を使ってページング処理を実装する (4:00)
  • 【ブログ】TeamGeekを輪読会の感想 (3:00)

『Webを支える技術』を読んで学んだこと

f:id:Saki-Htr:20210228190546p:plain

フィヨルドブートキャンプの課題である、「Webを支える技術 -HTTP、URI、HTML、そしてREST」(以下、「Webを支える技術」)」を、techplay女子部で輪読会をして読み終わったので、REST,URI,HTTPを中心に学んだこと・感想を書いた。

<<無断転載にならないよう気をつけて書いたつもりですが、もしご指摘等ありましたら修正あるいは削除させていただくつもりです>>

活動内容

  • 期間:11/15(日)〜12/24(木)
  • 人数:2人→途中から3人
  • ツール:zoom / HackMD
  • 時間帯:毎朝6:00~7:00 (起きられなかったら無し)
  • 形式:予習なしで、その場で読む。10分各自で読む&疑問や感想をHackMDに書く、次の10分で話し合い。これを3回繰り返して1時間。

本の構成

  • 第1部 Web概論
    • 第1章 Webとは何か
    • 第2章 Webの歴史
    • 第3章 REST
  • 第2部 URI
    • 第4章 URIの仕様
    • 第5章 URIの設計
  • 第3部
  • 第4部 ハイパーメディアフォーマット
  • 第5部

REST

アーキテクチャースタイルとは

RESTはクライアント/サーバーから派生したアーキテクチャースタイル

下記の文章の意味が理解できなかったので整理した。

実はRESTは、クライアント/サーバから派生したアーキテクチャスタイルなのです。素のクライアント/サーバアーキテクチャスタイルにいくつかの制約を加えていくと、RESTというアーキテクチャスタイルになります。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.26 より引用)

クライアント/サーバとは

  • アーキテクチャスタイルは、REST以外にも存在し、クライアント/サーバはその一つ
  • クライアント/サーバー:クライアントとサーバがHTTPというプロトコルで通信して、クライアントはサーバにリクエストを送り、サーバはそれに対してレスポンスを返してあげる方式
  • 単一のコンピュータ上ですべてを処理するのではなく、クライアントとサーバに分離して処理できることが利点。
  • RESTはこれに制約を加えたもの

制約とは

制約とは、以下の5つのアーキテクチャスタイルを指す。

  1. ステートレスサーバ

    • サーバー側で状態をもたない(リクエストする度毎回クライアントのことを忘れている/はじめまして)
    • HTTPをステートフルにするcookieはRESTの観点からすると、誤った拡張。しかし使わないわけにもいかないのが現状なので、必要最低限に使う。

  2. キャッシュ

    • 一度取得したリソースをクライアント側で使いまわす方式。
      例:「戻る」をクリックすると初めて接続したときより早い

  3. 統一インターフェース

    • インターフェースとは:プログラム同士の接点
    • 統一インターフェースとは:URLで示したリソースに対する操作を、統一した限定的なインターフェースで行う事。
    • メリット:インターフェースが統一されている事で、Webを利用しているシステムは同じHTTPメソッドで接続ができる。制限を加えることで、アーキテクチャをシンプルにできる。

  4. 階層化システム

  5. コードオンデマンド

    • プログラムコードをサーバからダウンロードし、クライアント側でそれを実行する
      例:JavaScript

結論

  • クライアント/サーバーというアーキテクチャスタイルに、この5つのアーキテクチャスタイル(制約)を加えたものがRESTである。
  • 実際にRESTに基づいて設計する時は、現実的にすべてのアーキテクチャスタイルを取り入れることができないこともあるため、いくつかを除外してもいい。

リソースとは

URI(URL)

クールなURIは変わらない

ブックマークに登録してあったお気に入りのWebサイトがある日突然見えなくなる、苦労して作成したリンク集が1年後には半分以上リンク切れ、検索エンジンの検索結果に出てくるページが見つからない
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.53より引用)

  • なんと、1990年代後半までは、URIが変更になることは日常茶飯事だった。=Webの根幹を揺るがす問題
  • Webはそれぞれのリソースにほかのリソースへのリンクが埋め込まれたハイパーメディアシステムなのに、リンクが切れてしまうということは、ハイパーメディアシステムが機能しないことになる。
  • Webの発明者ティム・バーナーズ=リーはこの状況を憂い、1998年に「Cool URIs don't change」(クールなURIは変わらない)」を発表した。

  • 自分が生まれたのが1995年なので、その頃にURLが変わっていてせっかくブクマ登録しても404になってしまう、という事態が信じられない...。

URIを変えないようにするための設計指針

 1. URIにプログラミング言語依存の拡張子を利用しない(.pl、.rb、.do、.jspなど)
 2. URIに実装依存のパス名を利用しない(cgibin、servletなど)
 3. URIにプログラミング言語のメソッド名を利用しない
 4. URIにセッションIDを含めない
 5. URIはそのリソースを表現する名詞である

(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.57 より引用)

指針について補足

  • 3.のメソッド名 = プログラミング言語のメソッドのことを言っている。(例)RubyのArrayクラスのsizeメソッド
  • CGIは廃れている
    Web技術の基本で学んだCGIが、この本では廃れた技術と書かれていた。2010年に発売した本なので2020年現在だと更に使われなくなっていそう。

    リクエストのたびにプロセスを起動するCGI方式は性能面で難点があったため、そのほかの手法に取って代わられました
    (山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.55より引用)

  • 4.のセッションIDが何かについては以下の記事で説明。

シンプルなURLは、ユーザーの使い勝手も良くする

  • シンプルだとその分文字数が少ないので、ユーザーが覚えやすい
  • 上記の1~5に該当しないURLは、ユーザーには馴染みがない

→文字数は少なく&シンプルにしよう。

階層で管理できない情報を表現したい時

  • 階層で管理できない情報を表現したいとき、例えばGoogleマップの位置情報を表現したいときは、マトリクスURIを使う。

地図中のある特定の場所を表現するURIには、緯度と経度のほかにも表示スケール(縮小・拡大)や地図か航空写真かのフラグなど、複数のパラメータが必要になります。しかもこれらのパラメータはそれぞれ独立した軸を持つため、個々のリソースを階層構造で表現できません。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.62より引用)

  • マトリクスURIは、複数のパラメ−タをセミコロン;で区切ってリソースを表現する。
http://hello.jp/map/lat=35.154328;lng=159.462784

URIが重要な理由

  • URIはリソースの名前である
  • URIは寿命が長い
  • URIはブラウザがアドレス欄に表示する

HTTP

HTTPのバージョン

アプリケーション状態とは

  • アプリケーション状態 = セッション状態
  • セッションとは:あるWebサイトにアクセス(あるいはWebシステムにログイン)して、ログアウトするかブラウザを閉じるまでが1セッション。1セッションで1ページしか閲覧しない場合もあれば、1セッションで何ページも見る場合もある。
  • セッション状態とは: 一連の操作の間の状態のこと。例:「ハンバーガーセットをポテトで注文している」という情報のこと。

HTTPメソッド

べき等性と安全性

  • べき等性:ある操作を何回行っても結果が同じであること。
  • 安全性:操作対象のリソースの状態を変化させないこと。 ※セキュリティ的な意味合いではないので注意。

→Webアプリを開発する時にこの2つがどう関わってくるのかイメージが湧かないので、今は「べき等性と安全性という性質がある」ということを覚えておく。

メソッドの間違った使い方

  • WebサービスやWebAPIの設計を誤ると、これらのメソッドが安全でなくなったり、べき等でなくなったりする
  • 例えば、GETの目的はリソースを取得することなのに、GETでリソースを更新したり、リソースを削除したりしてはダメ。
  • POSTは他のメソッドではできないことを色々できるが、他のメソッドでできることをPOSTにやらせてはいけない。
    特にGET,PUT,DELETEでできることをPOSTで行うとべき等性と安全性が損なわれる。
  • DELETEがべき等でなくなる例
    • /latestというURLがあり、「最新バージョンのリソース」を示すものだとする。
    • これをDELETEメソッドで削除すると、
    • 1回目:最新バージョンを消す
    • 2回目:1回目で消したバージョンの次に新しいバージョンを消す
    • 3回目:2回目で消したバージョンの次に新しいバージョンを消す...というようにエンドレスでバージョンを削除してしまう。

ステータスコード

ステータスコードの分類と意味

分類 意味
1xx 処理中
2xx 成功
3xx 他のリソースへリダイレクト
4xx クライアントエラー
5xx サーバエラー

ステータスコードは、クライアントとサーバーを疎結合にするための工夫

下記の文章の意味が理解できなかったので調べた。

ステータスコードを先頭の数字で分類するのは、クライアントとサーバの約束事を最小限に抑えて、クライアントとサーバの結び付きをなるべく緩やかにする、すなわち疎結合にするための工夫です。一般的に、システムが疎結合になると、コンポーネント間の独立性が高まり、コンポーネントの置き換えや拡張が容易になる、と言われています。HTTPで言えば、コンポーネントとはサーバとクライアントのことです。つまり、サーバのバージョンアップやクライアントの置き換えが行いやすい、ということです。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.113より引用)

疎結合とは

  • 疎結合と密結合という2つの概念がある。どちらも結合度(結びつきの強さ)を表す用語。コードでもこの2つの考え方がある。
  • 密結合
    • 処理を同一タイミングで行う場合に互いの処理同士の干渉が大きいもの。
    • コード同士が複雑に絡み合っている状態なので、長期的な保守を考えるのであればやめた方が良い。
  • 疎結合
    • 一緒に実現するコードが互いの干渉がなく一つ一つのクラス独立しているもの。
    • 将来的な拡張に柔軟に対応できて良い。

コンポーネントとは

  • 機器やソフトウェア、システムの構成する部品や要素。

結論

  • 本では「ステータスコードは、クライアントとサーバーを疎結合にするための工夫」と言っている。
    →たしかに、400番台だとクライアント側に原因があるエラー、500番台だとサーバー側に原因があるエラーというように、原因の所在がきっちりと分かれている
  • サーバーとクライアントが密結合だと、一方の何かを変えたい時にもう片方にも影響が出て処理が複雑そうだと思った。お互い独立している=疎結合である方が良い、ということだと解釈した。

ステータスコードは正しく割り当てる

  • Webサービス/WebAPIを開発するときに、ステータスコードを正しく割り当てないと、ブラウザ(クライアント)が間違った処理をしてしまうので、正しく割り当てることは最低限のマナー。
  • 例えば、本当は404 Not Found(リソースの不在)=エラーの状態なのに、404を返さず200 OK(リクエスト成功)を返す仕様にしているとする。
    これでは検索エンジンのロボットが404の状態をエラーでなく、正式なリソースと判断してしまう。
  • 開発しているWebサービスやWebAPIでエラーが起きたときに、どのステータスコードを返すかは、とても重要な設計の検討事項。とくに400番台は種類が多いので注意。

HTTPヘッダ

コンテントネゴシエーションとは

メディアタイプや文字エンコーディング、言語タグは、サーバが一方的に決定するだけではなく、クライアントと交渉(ネゴシエーション)して決めることもできます。この手法を「コンテントネゴシエーション」(ContentNegotiation)と呼びます。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.132より引用)

自分の言葉で説明してみた。

  • 英語と日本語の両方に対応しているサーバーに、日本語しか受け付けないリクエストをクライアントが送ると、日本語が返ってくる。
  • クライアント「日本語しか対応してないから日本語でよろしく」
  • サーバー「OK、日本語で返すね」

このやり取りのことを「交渉」と言っている。

キャッシュ用ヘッダ

  • HTTPの機能の一つ:キャッシュは、キャッシュ用ヘッダによって使える。
  • あるリソースがキャッシュ可能かどうかは、そのリソースを取得したときのヘッダで判断する。リソースがキャッシュ可能かどうか、その有効期限がいつまでなのかは、Pragma,Expires,CacheControlヘッダを用いてサーバが決める。

no-cashe=キャッシュ禁止ではない

  • 「キャッシュを使うな」という意味ではない。
  • 一度キャッシュに記録されたコンテンツは、現在でも有効か否かを本来のWebサーバに問い合わせて、確認がとれない限り再利用してはならない、という意味。

条件付きGET

以下の文章の理解が難しかったので、自分の言葉でまとめた。

クライアントがExpiresやCacheControlヘッダを検証した結果、ローカルキャッシュをそのまま再利用できないと判断した場合でも、条件付きGETを送信すればキャッシュを再利用できる可能性があります。条件付きGETは、サーバ側にあるリソースが、クライアントローカルのキャッシュから変更されているかどうかを調べるヒントをリクエストヘッダに含めることで、キャッシュがそのまま使えるかどうかを検証するしくみです。
(山本陽平 著 『Webを支える技術 -HTTP、URI、HTML、そしてREST』 p.146より引用)

  • クライアントが自分のローカルストレージに保存しているキャッシュを再利用したいので、ExpiresやCacheControlヘッダを検証したら、no-casheだったので、サーバーがリソースのキャッシュを禁止=再度サーバーにアクセスしなくてはいけないことが分かる
  • no-casheと返されていても、「条件付きGET」を送信することで、自分のキャッシュが使えるかどうか調べることができる
  • 調べ方=サーバ側にあるリソースが、クライアントローカルのキャッシュから変更されているかどうかを調べるヒントを、リクエストヘッダに含める。
  • 調べ方には2つある。
    • If-Modified-Since (要求)ヘッダ
    • If-None-Match (要求)ヘッダ

HTML

rel属性

  • rel属性とは:リンク元のリソースとリンク先のリソースがどのような関係にあるか。
  • HTMLを書く時、意味を分かっていないで、rel="stylesheet"と書いていた。これは「元のHTMLリソースを外部のCSSリソースにリンクするとき」に書く。
  • stylesheet以外にも色んな例がある。

リソース設計

リソース設計の手順

  1. Webサービスで提供するデータを特定する
  2. データをリソースに分けるそして、各リソースに対して次の作業を行います。
  3. リソースにURIで名前を付ける
  4. クライアントに提供するリソースの表現を設計する
  5. リンクとフォームを利用してリソース同士を結び付ける
  6. イベントの標準的なコースを検討する
  7. エラーについて検討する

  8. リソース設計の最初の工程は、サービスで提供するデータを理解し特定する作業。

  9. 自分のサービスでどのようなデータを提供するのかを理解していなければ、リソースは設計できない。
  10. 日本郵便が提供してるCSVのデータ
    →会社で使ってるシステムが、郵便番号を入れても住所が自動で入力されないので、これを使って実装できそう

  11. 機能の結果をリソースとしてとらえることが、重要

クエリパラメータ

標準的な利用コースを検討する

  • 利用コースという言い回しが難しく感じる。
  • つまり、このWebサービスをクライアントがどんな目的をもって、何を知りたくて使うかを想定して、どういうリソースのたどり方(=利用コース)をするか
  • 今回は、郵便番号を入力して目的の郵便番号リソースを取得するコース(この郵便番号てどこの市町村だろう?)/住所を入力して郵便番号リソースを取得するコース/地域リソースの階層をたどりながら郵便番号を選択するコース
  • 利用する人の立場に立って考えなければいけない。

全体の感想

  • 『Web技術の基本』を先に読んでよかった。初めて読んだ時は、知らない用語ばかりでちんぷんかんぷんだったが、2回目は、アーキテクチャースタイル、REST,URI,HTTPの基本的な知識、リクエストとレスポンスの裏側で何が起こっているか、リクエストメッセージの構成、を事前に理解していたため、理解することができた。
  • メンターさんから、Ruby on Railsを触った後や、就職した後に読んでみると、 理解度が変わってくると伺ったので、今回はREST,URI,HTTPの理解を優先し、それ以外は、実務で使うことになったらまた戻ってこようという気持ちでサラッと読んだ。
  • 触ったことがある技術とない技術で、読んだときの理解度が全然ちがうなと思った。
  • 輪読会についての感想は以下にまとめた。 saki-htr.hatenablog.com

参考書籍・記事

TwitterのURL設計を通して学んだこと

フィヨルドブートキャンプの「TwitterのURLを設計する」という課題を合格したので、URL設計について学んだことをまとめた。

URL設計とは

1. リソースにどんな名前をつけるか(どんなURLにするのか)
2. 決めたURLに対して、どのHTTPメソッドを使うか

を決めること。

Method Path Description
GET /foo fooの一覧を表示。
POST /foo fooを受け取って追加する。
DELETE /foo/123 fooのidを受け取って削除する。
GET /bar barの一覧を表示。

URL設計について書く前に、リソース,URL,HTTPメソッドについて説明する。

URLとは、リソースに名前を付けたもの

リソースとは

  • Web上に存在する、名前をもったありとあらゆる情報
  • URLと聞くと、Webページのアドレスを思い浮かべがちだが、他にも色々ある。
    例えば、Web上にある、

    • 写真
    • 文献・論文
    • 自分が登録したブックマーク
      なども全てリソースである。
  • リソースは、人の名前などと違って必ず一意の名前(その情報だけを指す名前)でなければならない。

URLとは

  • リソースに名前をつけたもの。
  • URLの基本的な仕様:uriスキーム/ホスト名/パス。もっと複雑な仕様もある。
  • TwitterのURL設計の課題では、このパスの部分を設計した。
  • ホスト名が一意であること & URLがそのWebサービスの中で一意になるように設計することで、リソースは世界で一意になっている。

HTTPメソッドとは

  • WebブラウザからWebサーバに対してのお願い。
  • 正式名称:HTTPリクエストメソッド

リクエストのどこに当たるのか

(HTTP入門 - とほほのWWW入門 より引用)

  • リクエストは以下の3つの部品から構成されている。
    1. リクエストライン
    2. リクエストヘッダ
    3. リクエストメッセージボディ

  • この2. リクエストヘッダの中にHTTPメソッドが含まれている。
    メソッド パス名 HTTP/バージョン

HTTPメソッド一覧

  • お願いには色んな種類がある。
メソッド 何をするか
GET リソースの取得
POST 子リソースの作成、リソースへのデータ追加、その他処理
PUT リソースの全部更新、リソースの作成
PATCH リソースの部分更新
DELETE リソースの削除
HEAD リソースのヘッダ (メタデータ)の取得
OPTIONS リソースがサポートしているメソッドの取得
TRACE プロキシ動作の確認
CONNECT プロキシ動作のトンネル接続への変更

※ LINK / UNLINK は、HTTP/1.1 ~廃止された。

POSTとPUTの違いは、URIの決定権

  • POST
    • サーバー側が決める
  • PUT
    • クライアント側が決める。
    • リソース名をクライアント側が指定して作成or更新をかけるメソッド。
    • 新規作成も更新も同じ書き方。
      例えば、PUT /articles/3421は新規作成かもしれないし、更新かもしれない。
      →リクエストされた時に、既存のリソースだったら更新し、新しいURLだったら新規作成する動作を行う。
    • 例:Wikipediascrapboxは、ユーザーが付けた記事のタイトルがそのままURLになっている。

(鬼滅の刃 - Wikipediaより引用)

  • Twitterの設計では、クライアント側がURLを決める必要性を感じなかったため、PUTを使った。

PUTは全部更新、PATCHは部分更新

PATCHメソッドは『Webを支える技術』には載っていなかったので、PUTとの違いを調べた。

  • PUTメソッド

    • べき等である
    • リソースの全部を更新
      ブログの記事に例えると、記事の内容を全部変えるのがPUT。
  • PATCHメソッド

    • べき等でない
    • リソースの一部分を更新
      ブログの記事に例えると、記事の台頭だけを変えるのがPATCH。
  • リソースの一部更新をする場合には、そのリソース (URL)へPATCHリクエストを投げるのが、最も自然な設計。
  • PATCHはべき等が必ずしも保証されていないメソッドのため、PUTとDELETEを組み合わせた設計のほうが、シンプルでねき等性のある設計になることもある。

  • Twitterの設計では、リソースを部分的に更新するような機能の設計はしなかったので、PATCHメソッドは使わなかった。

URL設計で気をつけること

  • パスのネストは最小限に抑える
  • 名詞を使う
  • ホスト名がこの世に一意であることと、URLが一意であることで、リソースは世界で一意となる。なので、URLを設計する時は、一意を示す設計をしなくてはいけない。
  • メソッドとパスの掛け合わせが重複しないようにする

メソッドとパスの掛け合わせが重複しないようにする

最初、以下のように提出した(一部抜粋)

Method Path Description
GET /user_id ユーザーを表示する
GET /tweet_id ツイートを表示する

レビューで以下のようにご指摘をいただいた。

  • このuser_id, tweet_idには、シンプルに考えると数字が入ってくる。
  • ユーザーのプロフィール画面を表示するURLと特定のツイートを表示するURLは別物だが、数字を入れてみると、URLとメソッドの掛け合わせが重複してしまうことが分かる。
Method Path Description 数字入り想定Path
GET /user_id ユーザーを表示する /128
GET /tweet_id ツイートを表示する /128
  • この設計は一見、/user_id/tweet_idで区別できているように見えるが、リクエストを処理するサーバにとってはまったく同じものに見えて区別ができない。
  • この問題を解決するために、サーバーがどのテーブル(リソース)を参照すれば良いか把握できるようにしてあげる必要がある。

このため、最終的に以下の設計にした。

Method Path Description
GET /users/:user_id ユーザーを表示する
GET /tweets/:tweet_id 特定のツイートを表示する

これなら、idの部分が重複しても、

  • /users/123
  • /tweets/123

となり、区別できる。

感想

  • 最初、Twitterの何がリソースに当たるか分からず、混乱した。
  • ツイートの新規作成画面を取得するリクエストと、ツイートを行うリクエストは、ブートキャンプの日報作成時のURLを参考にさせていただいた。
  • URL設計は、Sinatraのメモアプリ作成課題でも行うので、大事。
  • 設計はコードを書く時と同じで正解が一つでないので、
    課題修正時に、「なぜその設計にしようと思ったか?」を述べるようにしたら、メンターさんから、以下のように仰っていただけたのが嬉しかった🥰
    • 理由を述べることができるというのはとても大事な能力
    • ぜひ今後も「どうしてこういう設計/実装になったの?」と聞かれた時に答えられる姿勢で進めてほしい

参考書籍・記事

『Web技術の基本』を読んで学んだこと

f:id:Saki-Htr:20210228162526p:plain


フィヨルドブートキャンプで、「Webを支える技術 -HTTP、URI、HTML、そしてREST」(以下、「Webを支える技術」)を読むという課題があったが、必要な前提知識に不足があり、理解が難しかった。

この本が難しい場合は『イラスト図解式 この一冊で全部わかるWeb技術の基本』(以下、「Web技術の基本」)が、イラストが多く最初にイメージを掴むのに最適とアドバイスをいただいたので、そちらを先に読むことにした。

www.amazon.co.jp

読み終わったので、読んだ中で学んだこと・調べたこと、感想を書いた。


<<無断転載にならないよう気をつけて書いたつもりですが、もしご指摘等ありましたら修正あるいは削除させていただくつもりです>>


本の構成

ch1. Web技術とは
ch2. Webとネットワーク技術
ch3. HTTPでやりとりする仕組み
ch4. Webのさまざまなデータ形式
ch5. Webアプリケーションの基本
ch6. Webのセキュリティと認証
ch7. Webシステムの構築と運用

ch1. Web技術とは

学んだこと

  • HTMLを人が見やすいように変換しているのは、Webサーバーではなく、Webブラウザ

Webページが表示される流れ

  • 一度のコンテンツ転送で送られてくるファイルは1つ。
  • 画像など他のファイルがそのコンテンツに埋め込まれていて、転送が必要になったときはもう一度Webサーバーに要求してファイルを取得する。
  • 疑問:例えば、そのWebページに画像のファイルが10枚あったら、コンテンツに1回要求+画像ファイルの要求10回で11回要求するということか?
    →以下の記事によれば、読み込むファイル1つにつき、HTTPリクエストが1回増えてしまうため、ファイル数が多いほど、表示までの時間が遅くなってしまう とあるので、やはり、ファイルの数の分リクエストとレスポンスが行われているようだ。

なぜ全てのサイトがSSL化しないのか?

調べたこと

教わったこと

この疑問についてtechplay女子部のエンジニアの方が答えてくださったので、以下にまとめた。

→まとめると、今はSSL化することが当たり前で、していないサイトはほとんど無い。

CGIの仕組み

普通のホームページはスーパーで売っているお寿司と同じです。作り置きです。CGIでは、注文が入ってからホームページのファイルを作ります。
1.ホームページを見る人の注文をWebサーバ上にあるプログラムが受ける
2.注文を受けたプログラムが何かお仕事をする
3.注文を受けたプログラムがホームページのファイルを作って、ホームページを見る人に渡してあげる
の流れですね。
この流れを実現するためのあれやこれやがCGIです。

  • 注意:CGIはWebサーバ上でプログラムを動かすための「仕組み」であって、プログラム自体を表す言葉ではない

クライアントサイド・スクリプト

どんなプログラムかイメージしづらかったので、パスワードを登録する時に例えて考えた

  • 新しいWebサービスを使うために新規ユーザー登録をするとき、大抵は「パスワードの文字数は8文字以上、大文字小文字を混ぜる」などの条件がある。
  • クライアントがその条件を満たしてパスワードを設定できたかどうかは、誰が判断しているのか?
  • Webは同時に何百人もの人がアクセスしてくるので、サーバにやらせるのは非効率。
  • Google ChromeInternet Explorerなどのブラウザが、送られたプログラムを解析し、ユーザが入力したデータなどをチェックしてからサーバへ送信している。
    つまり、ユーザーがパスワードを条件通りに入力したかチェックしているのは、ブラウザ。
  • このチェックしているプログラムが、クライアントサイド。スクリプト

RESTful(RESTっぽい)とは

  • RESTは、「これが REST な実装である」という厳密な定義があるわけではない。
  • REST はアーキテクチャスタイル。スタイルなので、「REST っぽい」「REST っぽくない」といった語られ方をする。

考えたこと

  • HTMLを人が見やすいように変換してくれているのが誰かは考えたことがなかった。なんとなくWebサーバーがやっていると思っていた。
  • SSL化の背景についてここまで深く知ることは自力では不可能だったと思うので、教えてくださったエンジニアの方に深く感謝。今使われている技術がどういう背景で繁栄していったのかを知るのは楽しい。

ch2. Webとネットワーク技術

学んだこと

HTTP

TCP/IP

  • TCP/IP(プロトコルの集まり)は、役割ごとに4つの階層に分かれる。レイヤー1~4。
    クライアントとサーバーの両方にこの階層があり、同じ階層同士でプロトコルに従った処理をしている。
  • 処理の流れ:レイヤー1から処理が始まって、レイヤー1→2→3→4とデータが渡されていく
  • 階層を7つに分けた考え方もある=OSI参照モデル

IPアドレス/ドメイン

考えたこと

  • メンターさんに、TCP/IPの階層についてお聞きしたら、
    • Webエンジニアとして働く上では、「アプリケーション層/HTTP」の部分を理解していればOK
    • 他の階層については深く理解している必要はなく、階層になっているということが分かっていればOK

とのことだったので、今は、「階層に分かれている」ということを覚えておく。

ch3. HTTPでやりとりする仕組み

学んだこと

HTTPメッセージ

  • HTTPメッセージ=HTTPリクエストとHTTPレスポンスの2種類

HTTPリクエスト/HTTPレスポンス

  • HTTPリクエストの構成は、3つの構成でできている。
    リクエスト行/(メッセージ)ヘッダー/メッセージボディ
    • リクエスト行:どうしたい
    • ヘッダー:何を
    • メッセージボディ:どんな方法で
  • もし要求して応答されたwebページを解析したときに、画像のリンクがあったら、もう一度要求を送る。

f:id:Saki-Htr:20210227110159p:plain (HTTP入門 - とほほのWWW入門より引用)

HTTPメソッド

  • HTTPリクエストメソッド:簡単に言うと、WebブラウザからWebサーバに対しての命令(リクエスト)。
  • リクエスト(命令・お願い)には色んな種類がある。
  • Webサイト閲覧で主に使うのはGETPOST
  • 主に使われるメソッド
メソッド 動作
GET ページの取得を要求。WebブラウザからWebサーバに渡す値をURLの後ろにくっつけて送るやり方
HEAD ヘッダのみの要求
POST データをwebサーバーに送信
PUT webサーバーが保管してるコンテンツのアップロード(書き換え)
DELETE 指定したデータを削除
CONNECT SSL

HTTPバージョンの変遷

HTTP/1.0以前

  • リクエストを送信するたびにコネクションを確立し、レスポンスでデータを送った時にコネクションを閉じていた。
  • つまり、画像が埋め込まれていたらそのたびにリクエストを送る仕様になってるので、たくさん画像が埋め込まれているとリクエストの回数分だけコネクションの確立&閉じるをしなければならなかった。=効率が悪かった!

HTTP/1.1~

  • コネクションを継続利用できる、「HTTPキープアライブ」ができた。
  • HTTPパイプライン:複数のリクエスト&レスポンスを同時並行で行う。

HTTP/2

  • HTTP/2はgoogleが提案したSPDYという通信の高速化を目的としたプロトコルが土台。
    = HTTP/2の高速化を担う部分はほぼSPDYの機能を使っている。
  • 2での改良点①
    • 1.1のHTTPパイプラインは、HTTPリクエストの順番通りにレスポンスを返す。
    • つまり、1つのレスポンスの処理が重いと遅くなってしまう(高速道路で渋滞が起こっているイメージ)という問題があった。
    • この解決のために、コネクション上に仮想的な通信経路=ストリームを作った。
  • 2での改良点②
    • データのやりとりがテキスト形式→バイナリ形式に。前はテキスト形式だったので、バイナリ形式のデータを変換するのに負荷がかかっていた。
      • バイナリ形式のデータとは:コンピュータが直接的に処理するために2進数で表現されたデータ
    • そのため、ヘッダー情報を、2回目のやり取りからは追加情報(差分)だけ送るようにした。
  • 2での改良点③
    • 前はブラウザからリクエストが来たときに、画像が埋め込まれていたらその都度リクエスト&レスポンスのやり取りをしていた。
    • サーバーが、リクエストが来たときに必要なファイルを判別して、画像などのファイルもすべて返すようになった。(サーバープッシュ)

HTTP/3

  • 本には載っていなかったが、調べたら、HTTP/3がリリースされていた。
  • HTTPはステートレスなプロトコル。それをステートフルにしてくれるのがCookie
    例:ショッピングサイトのカートに入れた商品を次にログインしたときにも覚えてくれる。
  • Cookieが使用される目的は大きく分けて次の2つ
    1. Webサイトでユーザー情報を保存し、利便性を向上する
    2. ユーザー情報を取得し、広告配信に利用する
  • 仕組み
    1. ブラウザが初めてサーバーへ接続
    2. サーバーが、ブラウザに対してレスポンスを返す時に、ブラウザに保存しておいてほしい情報をCookieとして返す。 HTTPレスポンスに、set-cookieヘッダーを含めることで、Cookieを送信できる。
    3. 2回目以降、ブラウザはサーバーへ接続した時、HTTPリクエストにCookieヘッダを含めることで、Cookieを送信する。

セッション

  • セッション:クライアントがWebサーバーに接続してから切断されるまでの一連の行動を表す。
    クライアントとサーバーで通信を行う場合、クライアントからサーバーへ接続した時点でセッションが始まり、サーバーから切断するとセッションが終了する。この一連の流れを管理することをセッション管理という。
  • 例えばECサイトには、商品を探し、カートに入れ、購入するという一連の流れがある。このように同一利用者からのアクセスを関連性のある一連のアクセスとして扱いたい場合、Cookieを使ってセッション管理が行われる。
  • セッションID:一連のやりとり(セッション)を識別するための一意の数字。銀行の受付番号と同じ。セッションIDをクッキーに格納してやりとりをすることによってステートフルな通信ができる。
  • 各セッションにはIDが割り振られている。
  • セッションのデータはサーバーに保存され、セッションIDはブラウザに保存される。
    ブラウザがサーバーにリクエストする時、セッションIDを渡す→サーバーがIDに対応したデータを返す。
  • Cookieでユーザーの判別が行われ、セッションによってそのユーザーがとった行動と結びつけられることで、「通販サイトのカート内商品の保持」といった機能が実現される。

Cookieの問題点

  • Cookieは便利だが、プライバシー面・セキュリティ面において注意しておくべき点もある。
  • Tracking Cookie(トラッキングクッキー)
  • セッションハイジャック
    Cookieの識別子が漏えいする:右矢印:CookieにはサイトのセッションIDとともに、ログイン情報が含まれていることがある:右矢印:情報自体がSSLなどで暗号化されていても、セッションIDさえわかってしまえばサーバーに送ることで、ログイン状態が再現されてしまう。

考えたこと

  • HTTPが登場したのは1990年代らしい。私が生まれたのが1995年なので、想像していたよりも最近で驚いた。
  • HTTPの進化に感動した。私が小学生の時に父が使っていたPCは、Webページを表示するのにとても時間がかかり、画像も少しずつジワジワと読み込んで表示されていた。今はそんなことは有り得ず、wifiなどのネット回線に問題がなければ、たくさん画像が使われたWebページでも一瞬で表示できる。今ネットを便利に使えているのは、HTTPの進化のおかげなのだな、と思った。
  • HTTPのバージョンを知る方法を調べた。
    デベロッパーツールを開き、networkタブのProtocolを見ると、バージョンが分かる。

f:id:Saki-Htr:20210227112606p:plain

ch4. Webのさまざまなデータ形式

学んだこと

スクリプト言語

フィード

  • webサイトなどの更新履歴を配信するためのファイル。中身はハイパーリンクの集まり。
  • ブログやニュースサイトで使われる
  • webサイトにアクセスすることなく、最新情報をチェックできる

フィードリーダー

  • フィードを取得&管理するためのソフトウェア
  • お気に入りのwebサイトを登録しておくことで、わざわざそのサイトにアクセスしなくても最新情報や更新情報をチェックできる便利な情報収集ツール
  • ウェブサイトの見出しや要約、更新情報を記述したフィードを巡回・受信し、一覧表示するソフトウエア。RSS形式のフィードを扱うRSSリーダーを指すことが多い。
    = RSSリーダー

フィードリーダーは現在は衰退している

YouTubeやニコニコはストリーミング配信ではないのか

  • 本では、

YouTubeニコニコ動画などの多くの動画配信サービスはプログレッシブダウンロード配信

と説明されていたが、ストリーミング配信ではないのかと疑問に思ったため、調べた。

3つの配信方法の特徴・違い

  • 音声・動画の配信方法は3つある。
  • ダウンロード配信
    • ダウンロードを全部完了するまで再生できないが、完了すればいつでも再生できる
    • 例:Amazonプライムの動画をDLした時、途中までしかできていないと視聴することができない。
  • プログレッシブダウンロード配信
    • ダウンロードしながら再生
    • 疑似ストリーミング
    • 配信したファイルはユーザー側に残る
  • ストリーミング配信
    • ファイルを細かく分割し、細切れにしたデータをユーザーに配信して再生する
      例:ニコニコ生放送などのライブ配信
    • プログレッシブダウンロード配信との大きな違いは、動画データを端末にダウンロードさせない点。
    • 利用者のパソコンやタブレットに動画データが残らないから情報漏えいの心配がなく、セキュリティ的にとても安心な配信。

YouTubeを視聴する時に、見たい動画のURLや配信ページにブラウザで接続した時にしか視聴できないので、「いつでも再生できる」という説明が理解できなかった。ストリーミング配信ではないのか?

YouTubeを調べてみた

  • YouTubeで動画を見ると、映像の下に赤いラインとグレーのラインがある。赤いラインは再生した部分を示し、グレーの部分はダウンロードした部分を示している。 →このグレーの部分は、ダウンロードしている部分だった。
    f:id:Saki-Htr:20210227124307p:plain

  • 濃いグレーの部分は、まだダウンロードが完了していない部分。ダウンロード配信では、全部ダウンロードが完了していないと、視聴することができないので、YouTubeはダウンロード配信ではない。

  • よって、YouTubeニコニコ動画は、プログレッシブダウンロード配信であることが分かった。
  • プログレッシブダウンロード配信も動画データが一時的に端末へ保存されているので、目に見えづらかっただけで、YouTubeを視聴している時に、一時的にスマホやPCに動画が保存されていることが分かった。

考えたこと

  • このチャプターでは、webで使われている様々なデータ形式について学んだ。学習でさわったことのあるHTMLやCSSについてはすんなり理解できたが、この本で初めて知ったJSON,DOM,マイクロフォーマット,フィードなどは、触ったことがないので、読んでもイメージしづらかった。実際に学習や仕事でさわることになった時に、また読んで理解を深めたい。
  • 自分が使っていたAmazonプライム,Netfrix,YouTubeなどの動画配信サービスの配信方法が何かについて、考えるのが面白かった。

ch5. Webアプリケーションの基本

学んだこと

Webクライアント

  • Webクライアント = Webブラウザのみを指すと勘違いしていたので、調べて整理した。
  • Webクライアントとは
    • Webサーバー(Wepアプリケーション)にリクエストを投げるプログラム。
    • ブラウザ以外でも、http(s)で通信しているものは全Webクライアント
      1番使われているものはWebブラウザだが、スマホアプリ、WIndowsMacの専用アプリケーションなど、WebサーバーとやりとりしているものはWebクライアント。
    • つまり、Webブラウザ=Webクライアントでなく、WebブラウザはWebクライアントの(代表的な)一種

クライアントプログラム

CDN

  • CDNが何か、本の説明だけでは理解できなかったので、調べたことを整理した。

  • インターネットの世界にも現実世界と同じように「距離」の概念がある

  • 自分の使っているwebブラウザと相手のwebサーバーの距離が近ければ、それだけwebページを早く見られる。
  • 世界各地にwebサーバーを設置し、大元のwebサーバーからwebページのファイルをコピーしておく(お互い連携している=1つのネットワーク)
  • これによって、ホームページを見る人は、自分の近くにあるWebサーバからホームページのファイルを受け取れる。
  • このwebサーバーが集まったネットワーク(世界各地に分散されたキャッシュサーバーの集合体)をCDNという!

Ajax

  • 同期通信には、「リクエストを送ってレスポンスがかえってくるまで、クライアントは待つことしかできない」という欠点がある。
  • Ajaxという技術では、JavaScriptがクライアントとして直接webサーバーと通信をする。必要なデータだけやり取りするため、同期通信よりもサーバーへの負担が少なく済む。
  • JavaScriptのおかげで非同期通信が可能。
  • レスポンスを待つ間も、レスポンスに左右されない箇所のHTMLを更新したり、ユーザーからの入力を受け付けられたりするなど、レスポンス待ちの時間を有効活用できる→ページの更新が早くなる。

Googleマップの地図の表示部分で使われている

  • 具体的にAjaxがどのように使われているか疑問に思ったので、調べた。

  • Googleマップ地図をスライドすると、その先の地図が表示される。

  • これは、スライドしている間に足りない地図のデータをAjaxでリクエストしているから、ぬるぬると地図を動かすことができる。
  • 1回目の通信はリクエスト⇔レスポンス(同期処理)で行い、2回目からはAjaxという技術をつかって、JavaScriptに必要なデータ分だけを取ってきてもらう、という流れ。
  • もしAjaxがなければ、スライドする度にページを再読み込みする必要がある。

Web API

  • 本では、
  • ユーザーではなくプログラムが直接サービスを利用できるための窓口
  • アプリケーションがWebサーバーの機能を利用するためのインターフェース(接点)

と説明されていたが、意味が理解できなかったので、実際にWebAPIが使われているサービスを見て調べた。

  • 例えば、connpassというWebサービスを利用してイベントに申し込んだ時に、参加コメントをTwitterに投稿できる機能がある。

f:id:Saki-Htr:20210227132622p:plain

  • これは、コンパスがTwitterが提供している「ツイートする」WebAPIを利用しているため、ユーザーの代わりに事前にTwitterのWebサーバー(が提供してるWebAPI)からデータを取得することで、実現できている。
  • ユーザーはこれのおかげで、わざわざTwitterというWebサービスに自分で接続しなくても、connpassというWebサービス内から参加コメントをツイートすることができる。
    = 本の「ユーザーがWebブラウザから操作しなくても、アプリケーションが直接Webサービスを利用できます」という説明は、このことを言っている。

考えたこと

  • Googleマップを快適に使えているのはAjaxのおかげだったとは知らなかった。地図を移動する度に、ページを再読み込みしていたら非常に使いづらいと思うので、感謝。
  • 新しいことを学んだ時に、イメージが湧かない時は、実際のWebサービスのどの機能に当たるか、どこに使われている技術かを調べることで、理解を深められた。

ch6. Webのセキュリティと認証

学んだこと

  • すべての驚異や脆弱性への対策をするのは難しいので、一般的にはリスクによる損失の度合いを算出し、それに応じて優先順位を決めた上で対策する。

ファイアーウォールはどこに設置するのか

  • ファイアーウォールとは:企業などの内部ネットワークをインターネットを通して侵入してくる不正なアクセスから守るための防火壁。
  • 本の説明で、ファイアーウォールがシステムのどこに設置されているのか分からなかったので、調べた。

  • 外部ネットワークとDMZDMZと内部ネットワーク、それぞれの間にファイアウォールが入るような構造を作り、通信を仕分ける

  • DMZとは
    • 外部ネットワークと社内ネットワークの中間につくられるネットワーク上の区域
    • 外部ネットワークからも内部ネットワークからもファイアウォールなどによって隔離されている。
    • 外部に公開することが前提となるWebサーバは、常にリスクに晒されている。もし、Webサーバーを社内ネットワーク(=内部ねっと)に置くと万が一乗っ取られたり(リモートハッキング)、悪意のあるマルウェアなどを組み込まれたりした場合、社内ネットワークに接続されているその他のサーバやパソコンがすべて被害を受ける可能性がある。
    • 何のためにあるのか?→危険な地域のすぐそばに大切なものを置いておくのは危ないので、何かトラブルが起きても大丈夫なように緩衝地帯を設けて、そこに大切なものを置かないようにするためにある。
    • ファイアウォールDMZを置かない状態でも設置できるが、Webサーバと外部ネットワークの間に設置されるファイアウォールは広く開放されている状態で、警戒が緩く、外部からの攻撃に対して脆弱な状態。Webサーバが内部ネットワークに置かれていると、乗っ取られたWebサーバを踏み台にして内部ネットワークも簡単に攻撃を受けてしまうので、DMZが必要。

考えたこと

  • 自分が被害を受けたことがないのもあって、セキュリティについて深く考えたことがなかったが、ドコモ口座の不正アクセスなど、かなり身近な問題。
  • これから消費者側ではなくサービスを開発して提供する側を目指すので、きちんと学んでセキュリティ面も考えて開発ができるエンジニアにならねばと思った。
  • 個人情報の漏洩がどれくらいの頻度で起こっているか気になったので調べたら、知らないだけで意外と結構あった。自分の個人情報も気づいてないだけで結構抜かれているのではと怖くなった。

ch7. Webシステムの構築と運用

考えたこと

  • アプリケーション設計は、機能の一覧、アプリケーションの構成図、画面レイアウトなど表面的な部分の設計らしい。
    エンジニアとして就職したら、おそらく全部を自分でやるのでなく、
    • サーバーやセキュリティなどインフラをどうするかはインフラエンジニア
    • 機能の洗い出しなどはRubyを書いたりDB設計をするサーバーサイドエンジニア
    • 画面のデザインはWebデザイナーマークアップエンジニア、フロントエンドエンジニア

が主に決めたり各々同士が話し合ったりして設計ができるのだろうか。 これら全部を一人でする経験ができる、自作Webアプリ開発のカリキュラムが楽しみだと思った。

この事件はプログラムに問題があったわけではなく、伝達ミスによるもののようだが、気をつけないとこういう事態もあり得るのだな、と教訓になった。

全体の感想

  • この本はTECHPLAY女子部の方と2人で輪読会を行って読み進めた。
    輪読会についての感想は以下にまとめてある。

saki-htr.hatenablog.com

  • 一つ一つの用語を見開き1ページに丁寧に解説をしてくれており、ページの半分は図で解説してくれているので、初心者の私にとってとても読みやすかった。 Webを支える技術で分からない用語があった時に、この本を辞書代わりにして読むと良さそうだと思った。

DB設計で詰まったところ&どうやって理解したか

フィヨルドブートキャンプで、データベース設計(以下、DB設計)について学ぶプラクティスがあり、先日TwitterのDB設計の課題を合格したので、振り返りを書いた。

学習方法

  • 読んだ書籍
    • 『達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ』(ミック 著,翔泳社,2012年出版,全360ページ)
    • 『楽々ERDレッスン』(羽生 章洋 著,翔泳社,2006年出版,全240ページ)
  • 課題を解くために必要な部分を読む遅延評価法で学習した。一方の書籍に知りたい内容が載ってない時や疑問が出た時に、もう片方の書籍を読んで補完した。

理解に詰まったところ

1. 主キーは必ず一つのテーブルに一つだけと勘違いしていた

  • 『達人』の主キーの説明で、

主キーは一つのレコードを特定できるカラムの組合せ

と書いてあった。

  • しかし本に載っている、主キーを説明するテーブルには、主キーが一つのパターンしか載っていなかったので、主キーは一つのテーブルにつき一つだけと、勘違いしてしまった。
  • 勘違いしたまま『達人』の正規化の関数従属についての説明を読んだので、「主キーの一部」という言葉が出てきて混乱した。

どうやって理解したか

  • 以下の動画を見て、理解が誤っていたことに気づいた。
    • 主キー(わくわくアカデミー,2013/11/29投稿)
  • この記事の説明も分かりやすかった。

www.momoyama-usagi.com

  • 主キーは、一つのテーブルに一つある場合と複数ある場合がある。具体的には、主キーが何なのかについては、以下の記事に書いた。

saki-htr.hatenablog.com

2. ER図のリレーションシップ「1対0~多」の0とはどういう意味か

  • ER図のリレーションシップで、「1 対 0~多」の関係がある。 この「0」がどういう意味か理解するのが難しかった。

どうやって理解したか

  • テーブル同士の関係性を、現実に存在しているものに例えて考えてみると、分かりやすかった。
    Twitterの、ユーザーとツイートの関係について考える。

  • ユーザーから見た、ツイートとの関係

    • 1人のユーザーは、ツイートを複数回行うことができる。また、ツイートを1回もしないユーザーも存在する。よって、0~多
  • ツイートから見た、ユーザーとの関係
    • 1つのツイートは、必ずだれか一人のユーザーが作成したものである。よって、1
  • よって、ユーザー対ツイートの関係は、1対0~多である。

3. 外部キーはどうやって決めるのか

  • 『達人』を読む前に、『楽々ERDレッスン』の演習問題を解いたので、解説を読むと、いつの間にか外部キーができていて、ER図作成が完了しているので、過程がわからず混乱した。

どうやって理解したか

  • 外部キーは、正規化=関数従属を排除して新しいテーブルを作っていく中でできる。
  • 以下の解説動画を視聴して、関数従属を切り出して別にテーブルを作ることで、外部キーができることが分かった。

4. エンティティを抽出した後、どうやって正規化をすればいいのか分からなくなった

  • 『楽々ERDレッスン』の演習問題1を解いているところで、エンティティを抽出して、関連がありそうなカラムをテーブルに入れるところまで行った。

f:id:Saki-Htr:20210225151744p:plain

  • このテーブルの状態から、第3正規形まで正規化するにはどうすればいいか分からなくなった。
  • 自分の作ったテーブルと入れたカラムを見ただけでは、
    • どのカラムが主キーになるのか
    • どのカラムに2つ以上の値が入ってしまいそうか
    • どこに関数従属があるのか

が分からない。

どうやって理解したか

  • 上記の作ったテーブルに、色んなデータを登録してみたら、どこに複数のデータが入ってしまうのか分かりやすくなった。
  • 『達人』に載っていた正規化の説明が、一つのテーブルから始めていたので、作ったテーブル全てを一つのテーブルに入れてみた。

f:id:Saki-Htr:20210225152440p:plain

  • 実際にデータを登録する方法で方向性が間違っていないか、メンターさんにお聞きしたところ、「現場でも、実際にデータを入れてみて"あ!ここにミスある"って気づくことがある」と伺った。

感想

DB設計の手順を理解するのが難しかった

  • 課題を解く時に具体的なDB設計のやり方が分からなかった。
  • 『達人』でDB設計のやり方は、以下の4ステップと説明されていた。
1. エンティティ抽出
2. エンティティ定義
3. 正規化(~第3正規形まで)
4. ER図作成
  • しかし『達人』には、エンティティの抽出・定義の方法について詳しい説明が載っていなかった。
  • 逆に、『楽々ERDレッスン』には、エンティティの抽出方法についての説明はあったが、正規化とER図作成の手順については載っていなかった。
  • なので、具体的な手順を2冊の本を行き来して調べた。

本のどこが重要かの判断が難しかった

  • 私は分からない用語や理解できなかったことを全部日報に書いていた。そうしたら、メンターさんから「細かい言葉の定義はわかってなくていい」とか、「DB設計は仕事でよくやっているけど、「部分関数従属とか推移性関数従属とか意識して設計していない」、などアドバイスをいただいた。
  • 実際にTwitterのDB設計をした時に、「これは推移的関数従属だ」とか、「部分的関数従属だ」とかは意識していなかった。同じカラムが違うテーブルに複数ないようにすることを意識して設計することで完成できた。

  • 結局、自分が作ったテーブルに実際にデータを登録したときに不具合が起きないか&どういう風にデータを扱うかに重きを置くことが大事だと思った。

参考書籍/参考記事

Gitで課題提出するまでの手順をまとめた

Gitの使い方を忘れてしまっていたので、復習。

用語解説

  • ローカル:自分のPC
  • リポジトリ:履歴に関するデータを保管している場所
  • ローカルリポジトリ:自分のPCにある、履歴データの保管場所
  • リモートリポジトリ:専用のサーバに配置して、複数人でファイルを共有するためのリポジトリ。ここではGitHubリポジトリを指す。
  • ワークツリー:ファイルを編集する作業場。PCでコード編集していた場合、そこのことを指す。
  • インデックス:コミットするためのファイルを登録しておくためのスペース

Gitはどうやってファイルを管理しているのか?

  • Gitの目的は、変更履歴をたどれるようにすること
  • スナップショット(その時点の状態を、そのまま丸ごと保存したもの)で保存している

コミットするまでの手順

  • git initしてからコミットするまでの手順。

全体の流れ

# Gitに必要なファイルすべてを自動生成する
$ git init

# 変更をステージに追加する
$ git add

# 変更を記録する = コミットする
$ git commit

# ファイルの現在の変更状況を確認する
$ git status

1. git init

  • 実行は、ステージにあげたいディレクトリの直下で行う。
    例:sinatraメモアプリのコードをコミットしたいなら、/rubybook/sinatra_practice/で実行。
  • 何が起きるか?:Gitに必要なファイル(.gitディレクトリ)の全てが、このコマンドを実行したディレクトリの直下に自動生成される。
# /users/<ユーザー名>/rubybook/indexで実行
$ git init
Initialized empty Git repository in /Users/<ユーザー名>/rubybook/index/.git/

#=> 成功

# ls -aでファイルができているか確認
$ ls -a
./          ../         .git/       index.html
#=>.git/ができている

#.git/下に、Gitに必要なファイル全てが入っている
$ ls .git/
HEAD         config       description  hooks/       info/        objects/     refs/

2. git add

  • 何が起きるか?:変更をステージに追加する
# 今いるディレクトリ直下のファイル&ディレクトリ全てをステージに追加する
$ git add.

# ファイルやディレクトリを指定することもできる
$ git add <ファイル名>
$ git add <ディレクトリ名>

そもそもステージは何のためにあるか?

一部の変更だけをコミットしたい時、ワークツリーからステージにコミットしたい部分だけをステージにあげて、コミットするため。

3. git commit

  • 何が起きるか?:変更を記録する = コミットする
    git addでは、変更をステージに登録しただけで、まだ記録はされていない
$ git commit
#=>
[master (root-commit) 81fa678] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 <コミットしたファイル>

# コミットメッセージを一緒に入力する
$ git commit -m "<メッセージ>"
  • これでコミットは完了。

git status でファイルの変更状況を確認

  • git addgit commitする前に、どのファイルをadd&commitすべきか確認すべき。→git statusファイルの変更状況を確認する。
  • ワークツリーとステージ間の変更状況、ステージとリポジトリ間の変更状況の、2つの情報を教えてくれる。

ワークツリーとステージ間

  • 前回ステージに追加=git addしてから、ワークツリーのファイルに変更があるかどうか、を教えてくれる。
  • git statusしたときに、Changes not staged for commit::前回addされてからワークツリーに変更があって、それをまだgit addしてないよ!といっている。

ステージとリポジトリ

  • 前回コミット=git commitしてから、ステージに新しく追加された=git addされたファイルがあるかどうか、を教えてくれる。
  • git statusしたときにChanges to be committed::ステージに追加されているけど、まだコミットしてない変更があるよ!といっている。

実際にgit statusの結果がどうなっているか見てみる。

1.git commitまでしたファイルを編集して変更を加える

2.その後git statusで確認

$ git status
#=>
On branch master
Changes not staged for commit: #ステージに追加されてない変更があるよ!
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   index.html #$index.htmlに変更があったよ!
no changes added to commit (use "git add" and/or "git commit -a")


3.git addしてもう一度git statusを確認

$ git add .
$ git status
#=>
On branch master
Changes to be committed: #ステージに追加されているけど、まだコミットしてない変更があるよ!
  (use "git restore --staged <file>..." to unstage)
        modified:   index.html #該当するファイルはindex.html


4.git commit した後、git statusを確認

$ git status
#=>
On branch master
nothing to commit, working tree clean #コミットしてないファイルはありません

GitHubへアップロードする

  • git commitしたら、次にその内容をGitHub(リモートリポジトリ)にアップする。
  • GitHubにアップする理由
    • 自分が書いたコードを他の人に見てもらうため
    • ローカルリポジトリの内容をGitHubに保存しておくため

コミットしてからGitHubへアップするまでの手順

1.GitHub上で、保存したいリモートリポジトリを新規作成する。


2.アップする度に毎回リモートリポジトリのURLを指定するのは大変なので、ショートカットを作成する

$ git remote add origin <リモートリポジトリのURL>
  • これで、originというショートカットでアップできる。

  • 作成したショートカットの一覧確認と削除は以下のコマンドでできる。

# 作成したショートカットの一覧
$ git remote -v

# ショートカットの削除
$ git remote rm <ショートカット>


3.リモートリポジトリ(GitHub)へコミットしたファイルを送信する

git push <リモートリポジトリのショートカット名> <pushしたいローカルブランチ名>

# 例:originというショートカットに、mainブランチをpushする
git push origin main
  • ブランチが何かについては後で説明。

ブランチを作成してmainブランチにプルリクエストを送る

ブランチとは

  • ブランチとは、一つのプロジェクトから分岐させることにより、プロジェクト本体に影響を与えずに開発を行える機能のこと。並行で複数の機能を開発するために使う。
  • メリット:ブランチを作ることで、他の人の変更の影響を受けないですむ
  • mainブランチ(旧:masterブランチ)はリリース用のブランチとし、開発はトピックごとにブランチを作って進める。 mainブランチで開発してしまうと、リリースしているコードがどれか分からなくなったり、一個前のリリースに戻れなくなってしまう。
    →そのため、ブランチを切って開発し、最終的にリリース用のmainブランチへマージする(コードを取り込む)という流れで開発を進める。

プルリクエストとは

  • プルリクエストとは:自分の変更したコードをリポジトリに取り込んでもらえるように、依頼すること。
  • 課題提出で、「READMEだけmainブランチにpushして、それ以外のファイルを開発用ブランチに保管してプルリクエストを送る」と指定があったのは、最終的には完成したコードをmainブランチに取り込むため。だからmainとは別に開発用のブランチを作る。

手順

1. ブランチを新規作成

# ブランチを新規作成
$ git branch <ブランチ名>

# 作ったブランチの一覧確認
$ git branch

# リモートブランチも表示
git branch -a 
  • このコマンドは、作成をするだけで、切り替えはしない

2. ブランチの切り替え

# 切り替え
$ git checkout <行きたいブランチ名>

# 作成してそのまま切り替えたい
$ git checkout -b <新規作成するブランチ名>

3. プルリクエストを送りたいファイルをgit add & git commit する

  • 作成したブランチに切り替える前に、絶対add&commitしない!

4. GitHubへpushする

$ git push <リモートリポジトリのショートカット名> <pushしたいローカルのブランチ名>

5. GitHub上でプルリクエストを作成する

ここからはターミナルではなく、GitHub上で操作する。

1.リモートリポジトリのPull requestsをクリック

2.New pull requestボタンをクリック

3.baseには取り込み先のブランチ(main)、compareには取り込んでほしい元のブランチを指定。

4.pull requestをクリック タイトルとメッセージを入力してcreateをクリック

(Revieweresでレビュワーを指定できるが、今回はしない)

参考書籍,参考教材

週報 2/15(月)~2/21(日)

2/15(月)~2/21(日)の一週間の学習の振り返りをざっくり。

今週の目標&結果

今週の目標 結果
sinatraメモアプリの合格 ◎ 20(土)に合格
WebアプリからのDB利用の合格 ✕ pgを使ったDB接続は完了
/prepared statementを利用した実装がまだ
Railsの教科書(約100P)を読み終わる ✕ 残り6~8章
DB設計について学んだことをブログに書く
URLについて学んだことをブログに書く

今週の学習時間

ラクティス外の学習・勉強会への参加は含めない。

今週は目標時間をぴったり達成🎊

日付 目標 実際
2/15(月) 2:00 0:00
2/16(火) 2:00 3:00
2/17(水) 2:00 3:15
2/18(木) 6:00 9:30
2/19(金) 6:00 7:00
2/20(土) 6:00 7:15
2/21(日) 6:00 0:00
合計 30:00 30:00

今週やったこと

2/15(月)

やったこと

考えたこと

  • 目標を立てた時しか意識できてないので、忘れないように固定ツイートに貼った!これで忘れない💪

2/16(火)

やったこと

  • Railsの教科書p.1~20(1章の途中)
    • Railsをbundlerでインストール
    • rails new
    • rails sするために色々インストール&設定
  • 6:00-7:30 TeamGeek輪読会(最終回)

考えたこと

  • 1月頭から週3でやっていたTeamGeekの輪読会を読み終わった!読み終わって嬉しいが、終わってしまったのが悲しい。でもプラクティスを進めたいから、読みたい本ができるまでは、しばらく輪読会はお休みかなと思っている🤔
  • Railsの教科書が、とても丁寧で分かりやすい。
  • npm,Node.js,yarn,webpackerが何かわかってないので調べる。

2/17(水)

やったこと

  • rails sできるようにするために色々設定
    • nodeのバージョンを最新版から安定版にする
    • node -vとnodebrew lsの結果を同じにできた
  • rails g controller hello indexがうまくいかず →Webpacker can't find application.js とエラーが出たので解決にあたっていた

考えたこと

  • エラーメッセージを読んでも、そもそもwebpackerを初めて知ったので、何が原因か、どうしたら解決できるか分からなくて大変だった💦
  • 早くrails s ,rails gできるようになって学習を進めたい🥰

2/18(木) 休み

やったこと

  • rails -s できるようにするために設定いろいろ
    • 普段使ってるシェルをfish→bashへ変更
    • Error:homebrew-core is a shallow cloneを解決
    • railsコマンドが一切使えなくなったので解決。bundle installしたら直った
    • Rubyのバージョンを最新版3.0.0にアップデート
    • yarnをインストールしたらrails new,-s,-gできた
  • Railsの教科書:2-3章

考えたこと

  • なんとかrails new,-s,-gが実行できるようになった!
  • rbenvの切り替え方がわからず、ツイートしたところ、フィヨルドの方にアドバイスしていただいて、そもそもrbenvの仕様を理解していなかったことが原因と気づけた。アドバイスいただかなかったら気づけなかったと思うので、本当に感謝。
  • Railsの教科書、自分が実行したコマンドの裏側で何が起こっているか、非常に丁寧に解説してくれていて、Sinatraでやっていたのはこういうことだったのか〜と思いながら読んでいる。
  • コマンド数行でCRUD機能をもったメモが一瞬でできてびっくり仰天した🤯
  • fishシェルでrbenvのエラーが出たため、デフォルトシェルをfishに戻したが、自分がよく使うコマンドやディレクトリの候補を表示してくれたり、自分がいるGitのブランチを表示してくれたり、色々と便利なので、また戻そうか悩んでいる。
  • 30分弱仮眠したら午後も集中できた!睡眠は大事😄

2/19(金) 休み

やったこと

  • Railsの教科書
    • 4章完了
    • 5章途中(あと2pくらい)
  • Sinatraメモアプリのレビューを昼にいただいたので、修正
    • メモを新規作成するcreateメソッドと編集するeditメソッドがほぼ同じなので、createを消して、editのid部分を修正して新規作成時も使い回せるようにする
    • 提出物リンクリポジトリのトップなのでPRへのリンクに変更する。
    • PRページの下にREADME.mdがコンフリクトしていると警告が出ているので解消する→失敗
  • コンフリクトした原因が分からないので、提出時にどんなコマンドを実行したかを整理

考えたこと

  • Sinatraメモアプリ、プログラム自体には修正はほとんど無かったので嬉しかった!しかし、Gitのコンフリクトを修正できず、いろんなコマンドを試しているうちに、誤ってマージしてしまった💦Gitのプルリクエストを使った提出はこれが初めてで、操作に慣れていないので、実行するコマンドがどんな動作を行うのか理解してから実行すること、分からなければメンターさんに質問することを心がける
  • Bookクラスのメソッド定義のコードはどこのファイルに書いてあるんだろう?と疑問だったが、「諸々の仕組みはRailsActiveRecordが担ってくれていて、これを理解していこうとするともっと大変になるので、一旦ActiveRecordがとても便利だな、くらいの考えでもRails利用には支障がありません」とメンターさんから伺ったので、次に進む。

2/20(土)

やったこと

  • fishシェルを使いたいのでエラーの原因を調べた→未解決のまま
  • Sinatraが起動しなくなったので解決
    • brew postgresql-upgrade-databaseを実行
    • postgresql12をアンインストール
  • WebアプリからのDB利用
  • 昨日の日報提出

考えたこと

  • 昨日睡眠の質が微妙だったので、午後は集中力がかなり下がってWebアプリのDB利用はあまり進められなかった。今日はきちんと寝る!
  • URLもDBも知らない状態でいきなりrailsに入っていたら全然理解できなかったと思うので、おそろしい...
  • fishシェルが便利すぎて、やっぱりfishでruby,railsを使える方法がないか調べてたら時間がかかりそうだったので、後回し
  • 目の前のエラー解決は自分でできるようになったけど、その解決方法が長い目で見て良いかや、後々にこういう問題が起きてしまうかもということが分からないため、その場しのぎになっていないか不安。。というのもあって解決方法を細かく記録している。

2/21(日)

やったこと

  • 学習せず。

考えたこと

  • 木~土の3日間長時間学習していたので、4連休の最終日は力尽きてしまった...。目標の30時間は達成できたので良しとする。

今週の振り返り

✅ できたこと/できるようになったこと

  • sinatraメモアプリの合格
  • railsを問題なく使えるようになった
  • 今週はRailsがうまく使えなかったり、sinatraが起動しなくなったりと、エラー解決にあたることが多かった。Gitのコンフリクト以外は、全て自力で解決することができた💪

✅ "こうしたらもっと良かった"と思うこと

  • ラクティスを先に進めたいと思ってしまい、ブログでアウトプット等の復習が後回しになってしまっていたので、来週は復習する時間もきちんと確保する。長い目で見て、学んだことはしっかり振り返るべき。

来週の目標

Railsに本格的に入る前に復習に注力する。

  • データベース
    • TwitterのDB設計をどうやって行ったかまとめる
    • 他の受講生の提出物をチェック
    • 自己参照/自己結合の理解
    • 【ブログ】DB設計で学んだこと&詰まった点
  • REST
    • 【ブログ】web技術の基本/webを支える技術の感想
    • 【ブログ】URL設計で学んだこと
  • Git
    • 【ブログ】git init~プルリクエストの手順
  • 【ブログ】TeamGeekを輪読会の感想
  • 28(日)に必ず行う:2月の振り返り&計画の見直し

以下はできれば。

  • Railsの教科書の6~8章(最後)まで
  • book_appをリモートリポジトリのmainブランチにpushする