Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cookpad Summer Internship 2019 Day 1 Ruby TypeS...
Search
AKAMATSU Yuki
August 19, 2019
Programming
0
9.8k
Cookpad Summer Internship 2019 Day 1 Ruby TypeScript
AKAMATSU Yuki
August 19, 2019
Tweet
Share
More Decks by AKAMATSU Yuki
See All by AKAMATSU Yuki
今年できたチームの生産性を向上させたプラクティスの紹介 / Kaigi on Rails 2022
ukstudio
4
4.7k
Cookpad Tech Kitchen #24
ukstudio
0
680
Cookpad Summer Internship 2019 Day 1 Git
ukstudio
0
9.8k
sdevtalks.org開発報告 / reporting that sdevtalks.org was launched
ukstudio
0
310
GraphQL on Rails
ukstudio
1
400
「なんでも」をしよう / 2018-12-19 s-dev talks LT
ukstudio
2
500
Rails Developers Meetup 2018 Extreme
ukstudio
0
3.1k
機能追加時における 仮説検証/s-dev-talks-01
ukstudio
0
900
Rails Developers Meetup
ukstudio
6
3.3k
Other Decks in Programming
See All in Programming
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
TypeScriptでライブラリとの依存を限定的にする方法
tutinoko
3
690
Micro Frontends Unmasked Opportunities, Challenges, Alternatives
manfredsteyer
PRO
0
110
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
10
1.3k
macOS でできる リアルタイム動画像処理
biacco42
9
2.4k
cmp.Or に感動した
otakakot
3
200
OSSで起業してもうすぐ10年 / Open Source Conference 2024 Shimane
furukawayasuto
0
110
Jakarta EE meets AI
ivargrimstad
0
130
as(型アサーション)を書く前にできること
marokanatani
10
2.7k
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
Quine, Polyglot, 良いコード
qnighy
4
650
役立つログに取り組もう
irof
28
9.6k
Featured
See All Featured
Being A Developer After 40
akosma
87
590k
Designing for Performance
lara
604
68k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Designing for humans not robots
tammielis
250
25k
What's in a price? How to price your products and services
michaelherold
243
12k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
65k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
10 Git Anti Patterns You Should be Aware of
lemiorhan
655
59k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
Transcript
Day 1 Web開発基礎 赤松 祐希
Ruby
ゴール • 簡単なWebアプリケーションの実装を通してWeb開発の要素技術に触れる • ちょっとしたWebアプリケーション「フレームワーク」であれば自作できそうと思っ て欲しい ◦ 個々の要素技術の詳細よりは、それぞれの関係性や概念的なところを掴ん で欲しい
Ruby基本文法
rbenv • Rubyのバージョンを切り替えるツール ◦ cpadインストール時に自動で入っています • 今回はRuby 2.6.3 を使用するので rbenv経由でインストール
◦ rbenv install 2.6.3 ◦ rbenv global 2.6.3 rbenv影響下全体で有効 ◦ rbenv local 2.6.3 実行したディレクトリ以下で有効(globalより優先される) ▪ .ruby-versionというファイルが生成される
bundler • プロジェクトで使うgem(RubyGems)を管理 • 使用するgemを明示できたり、バージョンを指定できたりする • rubygems.org以外でホストされているgemをインストールすることも可能 ◦ 例えばGitHub •
gemの雛形を作る機能などもある
Rackアプリケーション • RailsやSinatra、多くのRuby製Webフレームワークの理解においてRackという のが非常に重要 • Rackアプリケーションとして実装すると、様々なアプリケーションサーバーに対応 することができる ◦ 例: Unicorn、Puma
Rackが登場した背景 • 今までに多数のアプリケーションサーバーが登場してきた(恐らくこれからも) ◦ Puma、Unicorn、Thin、etc… • より良いアプリケーションサーバーが登場したときに、アプリケーションの改修コ ストを払いたくない! ◦ お互いにRackに対応することでコストが不要になる
• 元々はPythonで策定されたWSGIというアプリケーションサーバーとアプリケー ションの仕様が元になっている
ブラウザからの処理の流れ • Rackがアプリケーションとアプリケーションサーバーを仲介することで、アプリ ケーションとアプリケーションサーバーが依存せずにすむ
Rackアプリケーションの仕様 • callメソッドが定義されていること ◦ callメソッドは環境変数を引数として受け取る ◦ 環境変数にはHTTPリクエストのメソッドやパスが含まれている • callメソッドの返り値は以下の3つを含むArrayであること ◦
HTTPステータスコード ◦ HTTPヘッダ ◦ HTTPメッセージボディ
HTTPリクエストとレスポンス • クライアントからサーバーに「何を」「どうして欲しい」か指示するのがHTTPリクエ スト ◦ 何を = パスで表現 ◦ どうして欲しい
= メソッドで表現 ▪ GET=取得 POST=作成 PATCH=書き換え DELETE=削除 • それの返事がHTTPレスポンス ◦ どういう結果になったか = ステータスコード ▪ 200系=成功 300系=移動とか 400系=クライアント起因の失敗 500系= サーバー起因の失敗 ◦ 内容 = ボディ
サーバーサイドアプリケーションとは • HTTPリクエストを受け取り、何かしらの処理を行い、HTTPレスポンスを返すア プリケーション • ブラウザベースであればボディにHTMLを、APIであればJSONを入れて返すこと が多い • 最近はJSによるSPAなどもWebアプリケーションと呼ばれていると思うので、意 図的に「サーバーサイド」アプリケーションと表現しています
演習: Rackアプリケーションを書いてみよう • Rackアプリケーションを実装し、サーバーアプリケーションに「最低限」必要な要 素をつかむ • 演習用資料のSection 1をやってみよう
ルーティングの導入 • サーバーアプリケーションが「何をするか」はHTTPリクエストのパスとメソッドで 大体決まる • 例題ではRack::Requestのpath_infoとrequest_methodで処理を振り分けた • 今後エンドポイントが触れるにつれ分岐がどんどん増えていくので、コードの見 通しをよくするためルーティングを導入する •
ルーティングとはリクエストされたパスやメソッドに対して、それを処理するため のコードを割り当てること ◦ 厳密に言うとすでにルーティングしているが、もう少し構造だったものを実装 したい
Controller • 例えばRailsであれば /users にリクエストがあった場合 UsersController で処理 するというのが基本 ◦ RESTfulとかリソースとかの話があるが今日は割愛
• 今回もRailsにならってパスごとに処理するControllerを用意する
演習: Controllerの実装 • Section 2に従いControllerの実装を行う
View • レスポンスに含めるHTMLをもう少し複雑なものを扱えるようにしたい • Rubyスクリプト内に文字列として埋め込むことも可能だが可読性に問題がでるこ とが予想できる • そこでViewのファイルをapp.rbとは別の場所に切り出して記述できるようにする
テンプレートエンジン • 今回はERBを使用する ◦ Embedded RuBy の略 ◦ テキストファイルにRubyを埋め込むことができる •
他にもHamlやSlimなどがある ◦ こちらの方が記述量が少ない、HTMLの閉じタグ忘れを防げるなどの理由 により一般的 • サーバーサイドアプリケーションを作る場合、Viewを動的に生成したいことがほ とんどなので何かしらのテンプレートエンジンを使うことが多い
演習: Viewの実装 • Section 3に従いViewを実装する
Model • ControllerからViewに値を渡して表示できるようになった • そこで今度はデータベースから取得した値を表示するよう対応したい
リレーショナルデータベース(RDB) • Webフレームワークでは一般的なデータストア ◦ MySQL、PostgreSQLなど
SQL • RDBにおいてデータの操作や定義を行うためのクエリ言語 • ORM(後述)の登場によって、アプリケーション上に直接記述する機会は減ってき ているが、SQLを理解しておくことは重要 • ORMがどういうSQLを発行しているのか理解しておく ◦ ここを理解しておかないと非効率なクエリを発行してしまう、またそれの解決
手段がわからないなどが起きる • 複雑な集計はまだまだORMではカバーしきれないこともある
ORM • RDBとオブジェクト指向におけるインピーダンス・ミスマッチを解消する ◦ インピーダンス・ミスマッチ = データモデルの違いによるギャップ • ActiveRecordパターン ◦
RailsのActiveRecordは名前の通りActiveRecordパターンが元になってい る ◦ RDBのテーブルと1つのモデルを関連づける考え方 ◦ 例: Userクラスとusersテーブル • 注意: 1つのテーブルと1つのモデルを関連づけるのがORMではない ◦ 複数のテーブルを1つのモデルに関連づけるものもある • オブジェクトを通してSQLの実行やオブジェクトへのマッピング、DBのコネクショ ン管理なども行ったりもする
演習: データベースのデータを画面に表示 • データベースはSQLiteを使用 ◦ データベースサーバーが不要な軽量のDBMS ◦ セットアップが簡単 ◦ PostgreSQLやMySQLと比較すると機能が貧弱
• ORMライブラリは使用しない ◦ 規模感的に不要 ◦ SQLの結果とオブジェクトのマッピングを感じて欲しい
発展課題 • 個別のTodoを表示するページの実装 ◦ /todos/:id のルーティングをどうするか • Todoを保存するページの実装 ◦ フォームページの実装やPOST先のエンポイント
• app.rbのリファクタリング ◦ 例えばControllerやModelのクラスを外に切り出す • フレームワークとしてもっと汎用的に作る
TypeScript
ゴール • TypeScriptに親しむ ◦ 特に普段動的言語で静的型付けの言語を触ったことない人達 ◦ とはいえ、今回は型に関しては大分ゆるっといきます • 非同期処理について理解する ◦
APIの呼び方 ◦ 非同期処理の実装方法 ▪ Day 3でも登場するので、今日頑張って理解してください
フロントとサーバーの分離 • Webフロントエンドが複雑になるにつれ、フロントとサーバーが分離することが増 えてきた ◦ APIサーバーとそれを呼ぶクライアントアプリケーション ◦ MVCのVが複雑化・独立してきたとも言える • jQueryだけでは戦えない世界
JavaScriptとTypeScript • 以前よりマシとは言え、複雑なクライアントサイドアプリケーションを実装するに はJavaScriptの言語機能では厳しいことも多い • TypeScriptはJavaScriptに静的な型機能を提供するトランスパイラ ◦ 個人的には原則TypeScriptを導入するのがオススメ ◦ 型機能をフル活用しないにしてもTypeScriptの方がJavaScriptより厳格
環境構築 • Visual Studio Codeのインストール ◦ フォーマッターのPrettierも入れる • Node.jsのインストール ◦
マシンにnodebrewが入っているはずなのでそれを使う
Visual Studio Code • TypeScriptを書くにあたってコード補 完や型定義の参照などで便利 • とりあえず覚えてほしいショートカット ◦ ファイル検索
cmd+p ◦ コマンドパレット cmd+shift+p ◦ ターミナル ctrl+shift+` ◦ 定義へジャンプ F12
TypeScirptのコンパイル • tsc --init ◦ TypeScriptのコンパイル設定が生成される ◦ デフォルトから以下の3点を変更します ◦ noImplicitAnyをfalse
◦ outDirをdist ◦ includeに[“src/**/*”] • tsc ◦ TypeScriptをJavaScriptへコンパイルします
noImplicitAnyについて • 型定義がない変数はany型(つまり何でもいい)になる • noImplicitAnyがtrueだと暗黙のany型が許容されなくなる • 今回falseにした理由 ◦ 型をつけるということになれていないと結構しんどい ◦
falseでも十分にTypeScriptの恩恵を得られる
演習: TypeScriptをコンパイルする • 演習資料 Section 1を参考に環境構築、TypeScriptのコンパイルまでやろう
基本文法: 変数
基本文法: 関数
基本文法: クラス
基本的な型 • boolean • number • string • array •
tple • any • void
型推論 • 変数などの型を明示的に指定し なくても型システムの方で推測 し、型を決定してくれる仕組み ◦ 推測できない場合、anyや neverなどになる
演習: TypeScriptに慣れる • 演習資料 Section2を写経してみよう • 他にも以下のことを試してみよう ◦ 型と違う値を入れようとしたらどうなるか ◦
複数の型の要素を1つの配列にいれたらどういう型に推論されるか ◦ dist以下の生成されたJSとsrcのTSを比較してみよう
DOMとDOM API • HTMLをツリー構造として表現、操作すること ができるAPIとその仕様 • HTMLを変更して画面を書き換えることが多 かったJSとは関係が深い • DOM
APIの例 ◦ getElementById ◦ createElement ◦ addEventListener
イベント • Webフロントエンドでは画面上やプログラム内で起きたイベントをトリガーに処 理を実行したいことが多い • イベントの例 ◦ HTMLの読み込みが終わった ◦ ボタンがクリックされた
◦ ユーザーがキーボードのキーを押した
addEventListener • ある要素に対して特定のイベントが起きたときの処理をコールバック関数で指 定する • ちなみにaddEventListenerに限らず、関数に別のコールバック関数を渡すの は頻出
演習: DOM APIを使ってみる • HTMLファイルを用意し、コンパイルして生成されたJSを読み込む • HTML上のボタンがクリックされたらbodyタグに新しくdivタグが追加されるよう にする
非同期処理 • 応答に時間がかかる処理などを行う際に は非同期処理をすることが多い ◦ Web APIの呼び出し、ファイルアップ ロード、ファイルシステムへのアクセ ス •
同期的に処理をすると応答を待つ間プロ グラムの実行がブロックされるなど、ユー ザーの体験を損う
非同期処理の方法 • コールバック • Promise • Async Function(async/await) • 上記3つそれぞれについてWeb
APIを叩くコードを書きながら学習していきま す
httpモジュール • Node.jsの標準モジュールの1つ ◦ 若干低レベルなインターフェースなのであまり使い勝手はよくない • HTTPサーバーやクライアントとしての機能を提供
APIサーバー • Sinatraで簡単なAPIサーバーを用意 • エンドポイントは以下の2つのみ ◦ /users ◦ /users/:id/todos
演習: httpモジュールでAPIを呼ぶ • Section 4、5の2つをやってください • 細かい構文のことよりhttp.getの第2引数のコールバック関数に着目してくださ い
非同期処理のネストは辛い • ある非同期処理を完了したら更に別の非同期処理を行いたい時はままある • 今回は2段階のネストだけどこれが3段階、4段階だったら…?
Promise • Promiseとは非同期処理を抽象化しオブジェクトとして扱えるようにしたもの ◦ 厳密に言うとPromiseという非同期処理のデザインパターンをJSに組み 込んだもの • Promiseの導入により、非同期処理のインターフェースを統一できる ◦ コールバック関数の場合、コールバック関数の引数が使用などで決まっ
ているわけではない
Promise(2)
演習: Promiseでコードを書き直してみよう • Section 6のコードを書いて実行してみよう • 今回はAPIがエラーを吐いたときの対応も入れてあります ◦ rejectの感じを掴んで欲しい
Fetch API • XMLHTtpRequestの代わりとなる非同期通信のためのAPI ◦ IE対応が必要の場合はPolyfillが必要 • Node.jsも対応していないのでNode.js環境ではnode-fetchモジュールが必要 ◦ 今回はnode-fetchモジュールが必要
• fetchはPromiseのインスタンスを返すので、そのままthen/catchなどが使え る ◦ httpの場合、Promiseインスタンスを自分で作る必要があった
演習: Fetch APIを使う • Section 7のコードを書いて実行してみよう ◦ httpをPromiseでラップしてた時にくらべて大分ラクなはず
Async Function(async/await) • Async Functionは非同期処理を行うための関数を定義する構文 • 現在でもっともモダンな書き方 • Async Functionとして定義された関数は必ずPromiseのインスタンスを返す
◦ つまり構文が違うだけで中身的にはPromiseなのでPromiseの理解が重要
演習: Async Functionで書いてみる • Section 8をやってみる • asyncと関数定義に書かれているのがPromiseを返す関数 ◦ つまり非同期に実行される
• awaitを付けて呼ぶとそこで非同期処理の完了を待つ