さあ、やっとプログラムを動かすことができそうです。
とりあえずホーさんに作ってもらったサンプルを使って、全世界に向かって「Hallow world!」と叫んでみます。
/////////////////////////////////////////////////////////////////////////////
よろしくおねがいします
Zeit Nowへの登録は完了していますでしょうか?
多分。githubでログインすればいいんですかね。
OKです。そうしましたら、今日はNowを使ってサーバーサイドの開発について説明します
初回のメンタリングで、Liberate liteでで必要なものとして以下をあげました 次に、バックグラウンド処理ですが、ここではゲームに必要な情報を計算したり、ブラウザに渡したりするところです。 ざっと思いつくところだと、 ・BOSSの攻撃力やアイコンのURLを取得 ・自分の所有NFTを取得(サービス名、NFT名など) ・ユニットの能力値を計算 あたりはバックグラウンド処理に該当します。 また、データベースにBOSSの情報を記載しておいて、データベースに接続して読み込む、といった処理もこちらで行います。 学習する必要があるのは、プログラミング言語であるJavaScriptと、 Firebaseか、Zeit Nowというサービスの使い方です。
この部分になります
本日の目標としては、 1. OpenseaのAPIを使って NFTを取得 2. NFTからユニットの能力値を計算 3. 能力値をフロントエンドから取得できるようにAPIを立ち上げ
というところまで(時間が許せば)行います
まずはNowの説明からです。
わかりました。
NowというのはPaaS(Platform as a Service)の一種で、自分でサーバを立てて環境構築しなくても、Nowが提供しているサーバ上にものすごく手軽にプログラミングをはしらせることができるサービスです。
コマンドでnowと打つだけでデプロイが完了するという、ものすごい手軽さがあります。また、デプロイすると自動的にURLが発行され、しかも最初からHTTPS化されています。便利です。
こちらをまずはインストールしていきましょう。
VSCodeを立ち上げて、WSLに接続してください
あがりました
それでは、 npm install -g now
と打ってみてください
Update available 5.6.0 → 6.13.6
あ、nodeのバージョンあげましょう
nvm install v12.13.1
nvm use v12.13.1
node --version
npm i -g now
前回NFT作るのにnodeのバージョンを8にしましたが、 Now Zeitはnode v12への移行を推奨しているので、一度nvmでv12系をインストールします
npm install v12.13.1ですか?
p出なくvです
nvm
Command 'nvm' not found, did you mean:
nvmはnodeのバージョン管理ソフトです(編集済)
Try: sudo apt install <deb name>
sudoしないといけない?
あれ、以前nvm入れたと思ったんですが
npm install -g now
now@16.7.3 preinstall /home/zap/.nvm/versions/node/v8.11.2/lib/node_modules/now node ./scripts/preinstall.js
/home/zap/.nvm/versions/node/v8.11.2/bin/now -> /home/zap/.nvm/versions/node/v8.11.2/lib/node_modules/now/dist/index.js + now@16.7.3 added 1 package in 6.434s
source ~/.nvm/nvm.sh
これでPATH通ると思います
動いたっぽいです。
okです。
そうしましたら、私が作ったテンプレートをダウンロードしましょう
git clone https://github.com/hoosan/liberatelite-backend
GitHub
Contribute to hoosan/liberatelite-backend development by creating an account on GitHub.
1行です
行けました。
それでは、 cd liberatelite-backend
でフォルダに入っていただいて
あ、というかVSCodeでそのディレクトリ開いてください
zap@DESKTOP-H0FTP1L:~/liberatelite-backend$ ls -l total 16 -rw-rw-rw- 1 zap zap 23 Jan 11 18:15 README.md drwxrwxrwx 1 zap zap 512 Jan 11 18:15 api -rw-rw-rw- 1 zap zap 273 Jan 11 18:15 now.json -rw-rw-rw- 1 zap zap 15192 Jan 11 18:15 package-lock.json -rw-rw-rw- 1 zap zap 266 Jan 11 18:15 package.json drwxrwxrwx 1 zap zap 512 Jan 11 18:15 util zap@DESKTOP-H0FTP1L:~/liberatelite-backend$
34.19 KB
右上のファイルみたいなアイコン押すと、Open Folderが出てくるので、それでさっきのフォルダ開いていただけますでしょうか
その方が見やすいです
78.87 KB
うまくいくとこんな感じで一覧で見れます
OKです。
はい、これがnowで使うファイル群になります
まず、使用言語はNode.jsというものです
はい。
これを使ってAPIを作っていきます
一番基本的な設定ファイルがpackage.jsonというやつです
開いていただけますでしょうか
はい
"name"というところにプロジェクトの名前が入っています
-sampleを消しちゃいましょう
liberatelite-backend-sample
"name": "liberatelite-backend",
OKです。
"dependencies": {} というところは、関連パッケージが記載されています。
今日使うのは、"express"というパッケージです
これでAPIを立てていきます
dependenciesに記載されているパッケージをインストールするのには、コマンドライン(ターミナル)で npm install と打ちます
node-fetchとurlも一緒にインストールされます
zap@DESKTOP-H0FTP1L:~/liberatelite-backend$ npm install added 54 packages in 2.55s
OKです
次、now.jsonを開いてください
これはnowで必要な設定ファイルです
さっきと同様に、"name"の-sampleを消しちゃいましょう
aliasもですか?
そうです!
"name": "liberatelite-backend", "alias": "liberatelite-backend.now.sh",
aliasのところの文字列が、APIを公開した時のドメインになります(編集済)
シェルなんですね。
.shってなってますよね〜 詳しいことはわからないですw
次に、app.jsを開いてください
utilってディレクトリに入っています
ありました
const express = require("express"); ここでさっきインストールしたexpressを読み込んでます
expressという変数に代入してます
JavaScriptでは、変数を宣言するときに、定数であればconstを頭につけます
あとで代入して書き換える場合はletです
const app = express();
この行で、expressの関数を使ってapp (applicationの略)を宣言します
このappでAPIを定義していきます
APIの設定は別ファイルでされているので、ここでは変数の定義(宣言)だけです(編集済)
expressがたくさん出てきて混乱するのですが
require("express");
最初のexpressは、モジュール名です
これをJavaScriptで呼び出して"const express"変数に代入しています
ここのconst expressはこちらで決めているので、 const exp = requre("express"); でも構いません
そこまではOKです。
ここで定義したconst expの実態は関数になっています。
この変数が関数になってるんですね。
exp()とすることで、関数を「実行」して、結果をappに代入します
const app = exp();
わかりました。
なので、1行目で const app = require("express")();
としても動きます
わかりにくいので分けるのが慣例です
module.exports = app;
最後の行で、他のファイルからappを読み込めるようにしています
ここまで大丈夫でしょうか
意味は分かりました。
読み込み方はわからないでとりあえずOKですか?
次にappを読み込んでいきます!
api/hello-world/index.jsを開いて見てください
はう
はい
1行目で、 const app = require("../../util/app");
となっていますよね
これが、先ほどみたapp.jsを開いて、その中でmodule.exportsされた変数を読み込む方法です
require("../../util/app");のappは、「ファイル名」に対応しています(編集済)
app.jsのapp
です
よろしいでしょうか
「module.exports」ってのが、「app.js」の戻り値を設定するみたいなコマンドなんですね。
そうですそうです
で、次なんですが app.get()という関数でAPIを作っていきます
APIにはGET, POST, PUT, DELETEみたいな、決まりごとがありまして
https://qiita.com/r_fukuma/items/a9e8d18467fe3e04068e
Qiita
HTTPメソッド(CRUD)についてまとめた - Qiita
こんにちは、Webエンジニア2年目の[@r_fukuma](https://twitter.com/r_fukuma)です! アウトプット練習も兼ねて,HTTPメソッド(CRUD)についてまとめました。 # HTTPメソッドの種類は...
あとでこの辺り読んでいただければと思います
わかりました。
app.getでは
20.36 KB
この部分を定義できます
リソースの取得です
get()の一個めの引数はapiのパス(url)に対応していますが、ここでは"*"になっています
urlはnow側で勝手に設定されます
あとでご説明します
app.get()の二つ目の引数は、関数になってます
JavaScriptではアロー関数といって
() => {}
この形で関数を表現できます
function() {}
でも良いのですが、function書かないで済むので() => {}を多用します
()の中に、関数の引数を設定できます
(req, res)
二つの引数が入っています
reqはrequestの略で、リクエスト時のurlパラメータ(前回メンタリングでやった?owner=みたいなの)などが入っています(編集済)
resはresponseの略で、apiのレスポンスを関数の中で設定していきます。
reqとかresは予約語なんですか?
いや、なんでも良いです
が、慣例としてreqとresをよく使います
なるほど。
その他大丈夫でしょうか
これって、reqの内容にかかわらず、resに「hello world!」って返す関数ってことです?
そうですそうです
ではnow.jsonもう一度見て見ましょう
"builds": [ { "src": "api/**/*.js", "use": "@now/node" } ],(編集済)
この部分が重要です
api/**/*.js にあるファイルをnowが自動的に見にいきます
今回だと、api/hello-world/index.js
が対応してます
で、hello-worldの部分がurlとして自動的に設定されます
やって見ましょう
ターミナルで、 now dev
と打って見てください
devは開発の意味で、ローカルにAPIを立ち上げて動作確認することができます
zap@DESKTOP-H0FTP1L:~/liberatelite-backend$ now dev
Now CLI 16.7.3 dev (beta) — https://zeit.co/feedback Ready! Available at http://localhost:3000/
OKです
http://localhost:3000/hello-world
ここにアクセスして見てください
あ
api忘れてました
http://localhost:3000/api/hello-world
ここでした
ディレクトリの階層がそのままurlになります
hello world!が表示されればOKです
hello world!ってでました
OKです〜
これであとは自分の好きな処理するだけです
が、もう少し説明します
これはアップロードをしたわけではなくで
はい
まだローカルです
ローカルで動かしているってことなんですよね?
そうです
では今度は now って打って見ましょう
今度はアップロードされます
now
って打つのは、
ログイン求められるような気がします
ターミナルです
一回now devをキャンセル
あ、そうです
すみません
ctrl+cです?
そうですそうです
時間かかります?
Stopping now dev server
この後帰ってこないんですが。
あ、もう一度ctrl+C必要かもしれません
ログイン求められました?
なんかemail送ったよ的な
登録したメールアドレスにメール送られてきます
はい、そのメールのverifyってとこクリックします
Githubで登録した場合は、Githubに登録するのに使ったメールアドレスかと思います
Error! The chosen alias "liberatelite-backend-sample.now.sh" is already in use.
あ、now.json保存しましょう
package.jsonも
これ、エディターって保存しないと変わらないんですか?
CTRL+Sです
はい、そうです
-sampleは私が使っちゃってるので、さっき変えていただきました
世界中の誰も使ってない名前じゃないといけないってことです?
そうです!
なるほど。
できたっぽいですね。
https://liberatelite-backend.zap.now.sh/api/hello-world
こんな感じでしょうか
このサイトは安全に接続できません
ご自分のユーザー名入ってると思うのでご確認ください
zapの部分ご確認ください
liberatelite-backend.zap.now.sh から無効な応答が送信されました。
Terminalに
Ready! Deployment complete [17s]
て出てます?その下なんてなってますかね
いけました。
あ、というかユーザー名入ってないのでいいんでしたすみません
なるほど。そういう事か。
https://liberatelite-backend.now.sh/api/hello-world
https://liberatelite-backend.haradatakeshi.now.sh/api/hello-world
こちらですね
あ、名前出ちゃってます
消したほうが
本名じゃないですね。
そうでしたかw
謎の名前を昔から使ってます。
いずれにしろこれで全世界公開完了です
ww
なるほど。面白いです。
簡単ですよね
前回のNFTの情報取るより簡単に見えますが、
前回のやつを組み込める自信がないですね。
あ、NFTとるコードも作ってます
VSCodeで、
なんと。
api/opensea-assets/index.js
開いて見てください
はい。
node-fetchというモジュールを使うことで、前回アクセスしたNFTのAPIにアクセスすることができます
APIのurlはここで定義してます const url = `https://rinkeby-api.opensea.io/api/v1/assets/?owner=${owner}&format=json`
$(owner)というところに、NFTのアドレスが代入されます
const { query } = parse(req.url, true); //owner=0x9ba9105d4a1cde23fa2ae25c67dea928b975d729 const { owner } = query; // 0x9ba9105d4a1cde23fa2ae25c67dea928b975d729
この部分でownerにアドレスを代入していきます
なお、//以降はコメントです
なんの値が入るかわかりやすいように書いて見ました
先ほどreqにはリクエストの情報が入ると申しましたが、 const { query } = parse(req.url, true); //owner=0x9ba9105d4a1cde23fa2ae25c67dea928b975d729
こうすることでurlパラメータの情報を取ることができます
イメージとしては、 http://localhost:3000/api/opensea-assets?owner=0x9ba9105d4a1cde23fa2ae25c67dea928b975d729
ここにアクセスした時に、owner=で定義されたアドレスをindex.js内で取得して、代入して https://rinkeby-api.opensea.io/api/v1/assets/?owner=0x9ba9105d4a1cde23fa2ae25c67dea928b975d729
ここにアクセスするという感じです
{ query }の波括弧の部分は、分割代入というやつで
parse(req.url, true)の返し値はjsonなんですが
{ "query": 〜〜〜, "何か": 〜〜〜 }
こんな感じ
{ query } とすることで、この中のquery部分だけ取り出すことができます
その下のownerも同じで
queryもjsonになってまして
{ "owner": 0x9ba9105d4a1cde23fa2ae25c67dea928b975d729, "他のパラメータ": ~~~ }
{ owner }とすることで0x9ba9105d4a1cde23fa2ae25c67dea928b975d729だけ抜き出すことができます
ここまで大丈夫でしょうか?
分割のされ方がちっとわからないです。
queryの中身が「owner=0x9ba9105d4a1cde2**25c67dea928b975d729」で(編集済)
ownerに代入するときに
「0x9ba9105d4a1cde23fa2ae25c67dea928b975d729」に区切ってるんですよね。
queryの中身はjsonです
{ "owner": 0x9ba9105d4a1cde23fa2ae25c67dea928b975d729 }
実際はこうです
const { owner } = query とすると、queryのなかの"owner"の値(0x9ba9105d4a1cde23fa2ae25c67dea928b975d729)を、ownerという変数名で定義できます
jsonファイルの変数名に仮に「name」というパラメタがあったら、
const{ name }で取れる的なことですか?
そうですそうです
queryも分割代入だから、jsonの入れ子になっているってことなんですか?
そです
なるほど。
fetch(url) .then((result) => { return result.json(); }) .then((data) => { res.send(data); }) .catch(() => { res.status(401); });
この部分は説明が必要ですが、ちょっと今日は時間がないので次回にしましょう
非同期の話が必要です
了解です。
ここにアクセスしてNFTの情報を取れることを確認しておいてください
とれました。
OKです〜
では本日はここまでです。 nowを使ったAPIの立ち上げ方のお話でした。
ありがとうございました。あともう少しで内部のことが書けそうな感じですね。
ですね。次回で非同期の話をして、そのあとはZAPさんの方でロジック書いていく段階になります
やっとプログラミングが始まりますw