雑食日誌スマートフォン用の表示で見る雑食日誌Vue.jsとServerless。JavaScript概要この記事は前回の記事の続きになります。Serverを構築しました。今回は、FireStoreのデータをGraphQLから取得するところまでやります。サンプルは以下のリポジトリにまとめてます。github.comデータの準備サンプルデータはインターネットムービーデータベースを使用します。Schemaは以下のように定義しました。MovieInfo型を持っています。MovieInfoには詳細な映画情報が入力されています。上記サンプルデータをFireStoreに追加します。追加したかったので愚直にFor文を回す実装をしました。db.collection("movies").add(movie);});Firebaseのコンソールからデータを確認できれば完了です。FireStoreコンソールクエリスキーマデータが準備できたので、SchemaのクエリとFireStreを接続してみます。今回、Schemaのクエリは以下の二つを実装します。クエリは映画の順位から上位10個のデータを返すクエリです。それぞれリゾルバーを実装してみます。フィールドに対して実行します。かければ上位10位以内の映画一覧を取得できます。ServerのリゾルバーはSchemaのフィールド名とTypeScript内のオブジェクトキー名が一致している必要があります。)リゾルバーを実装すると以下になります。}}デプロイしてクエリを実行すると以下のようになりました。映画ランキング一覧クエリ結果ランキング順に取得できています。(1位が欠損しているのが気になりますが。ソートするキーを映画公開日にします。一回のクエリでは10件固定で取得でき、簡易的なページネーションを実装して、次の10件を取得できるようにします。(ここでは任意のページや任意の映画数をクライアントから指定できる実装はしません。受け取れますが、nullableのためFireStoreへのクエリに条件分岐を追加します。オブジェクトへの変換処理は映画上位ランキング一覧と同じです。含める必要があります。nullにするかを決めます。};デプロイして動作確認してみます。クエリ引数を空にして実行すると以下のようになりました。映画一覧クエリ実行結果(引数なし)映画一覧を公開順に取得できています。基に再実行してみます。映画一覧クエリ実行結果(引数あり)1回目とは異なるデータを取得できました。このままだと映画の公開日が一緒の場合、データが欠損してしまうので今後修正していきたいと思います。JavaScriptはじめにGraphQLのバックエンド実装は以下の方法があります。ServerはNode.jsによるGraphQLサーバーを構築するOSSです。クライアントだけではなくバックエンドも複数のデータソースから選択して実装することができます。Serverを実装してみました。Functionsを追加します。言語はTypeScriptを選択しました。YesTypeScript初期設定TypeScriptの設定を行います。ディレクトリ内で作業します。以下のように編集しました。Serverのサンプルと同じスキーマを実装します。関数の引数に代入しています。emulatorsを起動してみます。配下でNPMコマンドを実行してます。(http://localhost:5000/apollo-server-sample/us-central1/graphql).表示されたURL(http://localhost:5000/apollo-server-sample/us-central1/graphql)をブラウザで開くとGraphQLクライアントが表示されます。Booksからタイトルを取得すると画像のようになりました。Serverを実装してみました。デプロイが簡単なので、予想しいていたより早く実装できました。今後はFireStoreのデータを返す仕組みを作ってみます。Serverを構築するTweet広告を非表示にするもっと読むコメントを書く2019-12-04JavaScriptでURLエンコードJavaScriptURLクエリ内に別URLをもたせたい時にURLをエンコードする方法についてまとめます。今回はJavaScriptで実装しました。encodeURIはじめ、JavaScriptのencodeURIを試してみました。本ブログのURLを引数に実行してみます。encodeURI('https://keinumata.hatenablog.com/')'https://keinumata.hatenablog.com/'結果は引数と何も変わらないです。これはencodeURI関数がURLを構成する予約語(;,/?:@&=+$)およびエンコードせず使用できる非予約語(-_.!~*'())はエンコードしないためです。試しに空白を入れて実行してみます。a')'https://keinumata.hatenablog.com/?%20a'日本語もエンコードされます。encodeURI('https://keinumata.hatenablog.com/ジャヴァスクリプト')'https://keinumata.hatenablog.com/%E3%82%B8%E3%83%A3%E3%83%B4%E3%82%A1%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88'今回はURLのクエリに使用するため、予約語もエンコードしたいので他の関数を探してみます。encodeURIComponentencodeURIComponentはencodeURIと比較してURLを構成する予約語(;,/?:@&=+$)もエンコードします。エンコードせず使用できる非予約語(-_.!~*'())はエンコードしません。試しにencodeURIで試したURLを実行してみます。encodeURIComponent('https://keinumata.hatenablog.com/')'https%3A%2F%2Fkeinumata.hatenablog.com%2F'スラッシュやコロンもエンコードできました。Calendarの3日目の記事です。APIとTypeScriptを組み合わせについて紹介します。APIは関数ベースでコンポーネントを実装する機能です。関数ベースのため、機能の再利用性を高める役割を持っています。hooksやSvelteに近い機能です。公式のRFCに記載されているモチベーションの1つにTypeScriptとの相性を高めることが書かれています。本記事ではサンプルコードを踏まえてなぜTypeScriptと相性がよくなるのか考えてみます。https://vue-composition-api-rfc.netlify.com/#better-type-inference準備Vue2系で試す場合はプラグインが提供されているので、インストールする。CodeでVeturを使用している場合、設定を以下のように変更する必要があります。APIと比較してみたいと思います。今回は両方のAPIを使って同じ機能を持ったモーダルコンポーネントを実装してみます。機能としては以下になります。以下のGitHubにても公開しています。https://github.com/keinuma/compare-options-and-compositionテンプレートテンプレートおよびスタイルは共通のコードを使用します。(スタイルのコードは今回の記事では紹介しません。クリスマスになりました。アドベントカレンダーの最終日です。APIの場合は以下になります。APIの場合は以下になります。関数の中でデータやメソッドの定義を行います。関数から定義できます。使用してアクセスできます。インスタンス自身の2つの意味を持っていました。責務を分離しています。責務を分離することで型定義を推論を効かせしやすくしていると考えられます。関数だからこそ機能としての再利用性を意識しやすくなります。そのため、外部モジュールへの抽出や構造化が促進されると考えられます。Xというイベントに参加してきた。豪華なスピーカー陣が5トラック並行にセッションするため、何を聞きにいくか一番悩んだイベントだったと思う。色々な分野の有力者の方々から深い話をたくさん聞けて面白く、多くの学びがあった。devlove.wixsite.com特に印象に残った講演をふりかえっていく。剛speakerdeck.com今回のイベントで一番考えさせられたセンションだった。最近の開発ではチームに着眼したふりかえりを実施するものの、個人に焦点を当てたふりかえりはなかなか広まっていない。エンジニア個人の成長を考えると一人のふりかえりがより重要ではないかというお話だった。私自身一人のふりかえりを実施していたが、以下の新しい観点を得られた。KPT/YWTに加えて感情を言語化するふりかえりした結果を共有する私は自分の嫌な一面やみたくないところと向き合いたくないから感情を言語化することを避けてきていたように感じる。セッションを聞いて、感情と向き合うことで自分のモチベーションを知ることができ、成長につながることがわかった。自分のことは十分知っているだろうという認知バイアスにかかっていたことを自覚させられた瞬間だった。個人のふりかえりを共有することは気恥ずかしさがあり一人ではやるという発想にすらいたっていなかった。自分が見えない観点をフィードバックしてもらえることは重要だと気付かされた。ふりかえりの結果、学んだことは習慣化しないと意味がなくなる。無意識におこなわれる習慣にうまく組み込めるようにルーチンを作っていきたい。Kawashimawww.slideshare.net最近私はエンジニアとしての働き方、役割が変わり、言われた物を作るよりも価値のあるものを作ることにコミットするようになってきている。間違って認識し、作り始めるスピードを正としてきはじめた自分にはいい教訓になった。考えることを安易に止めず、本当はもっといい設計があるのではないか、考えることに時間を使う方が投資対効果が高いこともある。どこまでが本当にユーザーに問わないとわからない領域でどこまでは思考することで最善を尽くせるのかバランスを意識しないといけないと解釈した。具体的な設計では状態や区分を実装するときにインターフェースを切る考えを学んだ。ホットスポットを見つけるツールも使っていきたい。光起speakerdeck.com過去の経験から自分を知り、学びを抽象化する具体的な方法を知ることができた。エンジニアの自分にとっては「エンジニアリングが好き」で考えを止めず、さらに目的を深掘りしていくことが学びになった。自分なりに解釈すると、以下のようなる。経験してきた中で印象に残るストーリーを切り出すストーリーから事実(仕事)と感情を洗い出す並べた事実と感情がなぜ起きた/感じたかを問い直す問いに答えてさらに問い直すことを重ねて学びに抽象化するこれらから自分は作ることよりも価値を届けること、使ってもらえることにモチベーションを感じることが改めてわかった。他にも紹介されていたキャリアアンカーやストレングスファインダーをやってみたいと思う。陽太郎poohsunny.hatenablog.comアウトカムは重要であると同時にエンジニアの楽しさにも経験を通して繋がっていることを学んだ。セッションを聞くまでプロダクト作りは成果にコミットできいないと意味がないけれども、全員のエンジニアの楽しさにつながるわけではないのではないかと思っていた。エンジニアは技術領域と何を作るかを決める領域のそれぞれ比重を持っていたからだ。センションを聞いたおかげで、足りないのは視座を高めたり詳細まで降りたりすることを共有することだと学んだ。コーディングという観点だけを見ると限りなく綺麗にしていきたいし、最適化したくなる。プロダクトとして何を目指していて、現在どういう状況なのかを共有し、理解することでチーム全員が同じ方向を向けるのではないかと思った。エンジニアに限らずチームメンバーがどの分野に興味があり、どこにギャップがあるか観察して思いを共有していきたい。まとめ今回のイベントからは一貫して学びを得ることの重要性を知れた。学びは自分だけでなく、チームやプロダクトにも当てはめることができる。これからは積極的に学びを得るためのフィードバックサイクルを早くしていきたい。Agile使いにくいプロダクトある案件で開発したプロダクトがユーザーにとって使いにくいと評価されることがあった。プロダクトの受け入れ条件を満たし、チームの中で認められたプロダクトであってもユーザーにとって価値が高いわけではない。頭でわかっていたつもりであってもはじめて経験したときに少なからず戸惑いがあった。すればユーザーにとって使いやすいプロダクトを開発できるのか試行錯誤している考えをまとめてみる。多くの開発では素早く正確に実装することが求められている。何を作れば正解かわからないプロダクト開発では変更容易性も兼ね備えなければならない。そのため私は以下のことを考えながらプロダクトを開発していた。設計指針から外れていないか責任を明確に分離できているかミスをしていないか可読性の高いコードになっているかこの時点で意識しないといけないことは多い...ふりかえるとエンジニアとして開発するときはミクロな目線で糸を縫うような作業をしているようだなと感じた。このうえでユーザビリティを高めるためにはユーザー目線を得る必要があると思った。ユーザー目線の獲得ユーザーの視点を借りるためにはどうすれば良いか。一番はユーザーにプロダクトを体験してもらうことだと思う。体験してもらっている様子を観察して、問いかけたり、プロダクトの感想を伝えてもらって方針を変えたり機能を追加していく。ターゲットユーザーに実際にプロダクトを提供するためには、多くの人を巻き込みプロダクトを一定レベルまで完成しないといけないためコストが大きい。プロダクトの方針一つ一つをユーザーに問いかける訳にはいかないので、一定レベルまでエンジニアがプロダクトを形作っていかなければならない。一定レベルまで仕上げるためにはエンジニアがユーザー目線を持たないといけない。エンジニアがユーザー目線を得るためにはユーザーに共感する必要がでてくる。共感するためには、バックグラウンドや感じる課題、プロダクトを使用するときに気にかけることなどを知らないといけない。これらからユーザー目線の獲得は一朝一夕でなくユーザーと対話を重ねることで作り手側にユーザー目線を宿していく深い経験ではないだろうか。理想の姿とは感じつつも常にエンジニアがユーザーと対話できる状況ではない。対話なしでもエンジニア個人の基準でプロダクトを作り続けられるようになりたい。違和感を感じる私が考えたユーザー目線に近づくためのアプローチはプロダクトの違和感を拾うことだった。違和感はプロダクトを初めて見たときに感じやすい。そのため開発を続けているとプロダクトの当たり前が自分の中に浸透してしまう。今まで開発してきたプロダクトではリストの見せ方やボタン配置・配色、ページ遷移時のインタラクションなどを当たり前にしてしまっていたように思う。この当たり前がチームの中に浸透してしまうと、ユーザーに見せるまで誰も疑問に思うことなくプロダクトを改善する機会を失ってしまうことになる。プロダクトを改善するためには意識的にユーザーになりきって違和感を感じることが大事なのではないかと考えた。目線を意識的に切り替える違和感を感じるためにユーザーになりきったまま細やかな開発を遂行するのは難易度が高い。私自身ミクロな目線とマクロな目線を同時に持ち合わせられるほど器用になれない。実装に集中するとき(開発モード)とユーザーになりきるとき(ユーザーモード)の二つを意識している。ユーザーとしてプロダクトを触って違和感を感じたらプロダクトバックログに追加する。追加したプロダクトバックログアイテムを元に使いやすさを求めて開発を進めていく。目線切り替えを繰り返していくと個人の中でプロダクトの改善サイクルが回り始める。改善を続けていても一人では限界がある。この限界は開発チーム全員が互いに目線を切り替えて、議論を重ねることで超えられるのではないだろうか。壁を超え続けたプロダクトはきっとユーザーにとっての価値に近づくと信じている。GraphQLはじめにある案件でAppSyncを使うことになったが、商用利用の事例が少なくデプロイ方法がわからなかった。FrameworkのAppSyncプラグインがあったので使ってみた。AppSyncとはAppSyncはAWSで利用できるGraphQLベースのマネージドサービスである。特徴としてバックエンドサービスを自由に切り替えることができるGraphQLベースのため、フロントエンドに必要なデータを定義できるなどがある。バックエンドにはLambdaやDynamoDB、HTTPなど多様なリソースを選択できる。今回の案件では以下の条件があった。現状AppSyncを商用利用して、デプロイするためには以下の手段が考えられた。CLIを使うCloudFormationを使ってデプロイするためにはYaml地獄と戦い、トライアンドエラーを繰り返す必要がある。時間的猶予がなかったため却下した。CLIはコマンド一つでAWSリソースを作ることができる強者である。以下の懸念点があった。CLIを使用しなかった。他に良いデプロイ方法はないか探していたら、以下の記事に遭遇し、ServerlessFrameworkのAppSyncプラグインを知った。Frameworkを使う予定があったので、試してみたら思いのほか手軽だった。ここからは実際にデプロイした手順を記録していく。FrameworkでAppSyncデプロイ今回はAppSyncのバックエンドにLambdaを使用する。SchemaにはブログWebアプリケーションを想定に実装する。サンプルはGitHubにもあげているので併せてみていただきたい。github.comCLIインストールNPMでインストールする。serverlessプロジェクト初期化プロジェクトを初期化する。オプションが必要である。種類は以下に詳細が記載されている。CloudFormationのもとになるYaml定義。Lambdaを使用する場合の実行ファイルのため、AppSyncのデプロイだけでは不要である。プラグインを管理していく。"ISC"}AppSyncプラグインをインストールする。-v"},これでデプロイを実行する準備が整った。整えながら、AppSyncの設定を加えていく。Framework共通設定はじめに基本設定を記述していく。開くと例が記載されているが、今回必要な部分は少ないので消す。デプロイ環境の総称となる。今回はプロジェクトのディレクトリ名を使用する。Providers(AWS)およびリージョンの設定をする。インストールしたAppSyncのプラグインを記述する。Cognitoを選択する。Schemaの詳細を以下に記載する。SourcesバックエンドにはLambdaを使用するため、二つのARNが必要になる。反映すると以下になる。Templatesを整える。ディレクトリに格納することでAppSyncに反映する仕組みになっている。Templatesは共通化させて設定した。ディレクトリ以下に格納する。ディレクトリ名は変更することもできる。反映すると以下のようになる。登録したコマンドでデプロイを実行する。ARNを仮で記載しているので、編集してから実行する。追加することで、実行の詳細を確認することができる。ファイルをコンパイルして、CloudFormationに変換し、S3バケットに格納する。ディレクトリにも保存される。S3に格納されたら、CloudFormationが実行され、定義したAWSリソースが生成される。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。