かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Fetch API 試してみた。

恥ずかしながらFetchAPIたるものがあるのを知らなかったので、ざっくり試してみた。

Fetch API

Service Workersでも使えて、プレーンなJavaScriptXMLHttpRequestより強力で柔軟な操作ができるそうです。

GET

fetch(api_url, {method: 'GET'})
  .then((res) => {
    // resはResponseオブジェクト
    console.log( res );
    // 返されたBodyをjsonにしてPromise.resolve()する
    return res.json(); 
  })
  .then((data) => {
    // api_url から返されたデータ(json) 
    // 実際にデータを加工したり色々する
    console.log( data );
  })
  .catch((err) => {
    console.error( err );
  });

GETメソッドの場合は第二引数のmethod: 'GET'を省略することができます。

FetchAPIで最初で取得されるデータはResponseオブジェクトになっており、res.json()を実行することで返されたデータのBodyをJSON形式にしてPromise.resolve()に渡すようになっています。
JSON以外にも次のようにArrayBuffer, Blob, FormData, Stringにすることもできます。

  • ArrayBuffer: res.arrayBuffer()
  • Blob: res.blob()
  • FromData: res.formData()
  • String: res.text()

詳しくはドキュメント: Response - Web API | MDNを参照

POST

fetch(api_url, {
  method: 'POST',
  // 送信するデータ
  body: post_data
})
  .then((res) => res.json)
  .then((data) => console.log( data ))
  .catch((err) => console.error( err ));

POSTで送信するデータはbodyオプションに指定します。
methodPUT, DELETEにすればPUT, DELETEのリクエストも送ることが出来ます。

PUT

fetch(api_url, {
  method: 'PUT',
  body: post_data
})
  .then((res) => ...)

DELETE

fetch(api_url, {
  method: 'DELETE',
})
  .then((res) => ...)

クロスオリジン (クロスドメイン)の送信

クロスオリジンで通信を行いたい時はmodeオプションにcorsを指定します。

fetch(api_url, {
  mode: 'cros'
}).then((res)...)

mode オプション

  • same-origin: *default 同じドメイン(same origin)のみ許可。クロスオリジンは接続エラー
  • cors: クロスオリジンを許可。レスポンスは表示できるヘッダが Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragmaに限定される

    cors and basic responses are almost identical except that a cors response restricts the headers you can view to Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, and Pragma.

  • no-cors: CORSヘッダーを持たないopaqueレスポンスを返すオリジン用。接続ができない場合にエラーとならずに空のレスポンスが返される。

    no-cors is intended to make requests to other origins that do not have CORS headers and result in an opaque response, but as stated, this isn't possible in the window global scope at the moment.

no-corsについてはイマイチ理解が出来ていないのですが、クロスオリジンにリクエストを送る際はmode: 'cors'としておけば良さそうです。

詳しくは Request.mode - Web API | MDNResponse Types Introduction to fetch() | web | Google Developersを参照

クレデンシャル (認証情報: credentials)

クッキーなどのクレデンシャルを送る場合はcredentialsオプションをincludeにする

fetch(api_url, {
  credentials: 'include'
}).then((res) => ... )

credentials オプション

  • omit: *default リクエストにクレデンシャル(認証情報)を含まない
  • same-origin: 同一オリジンの場合だけクレデンシャル(認証情報)を送る
  • include: クレデンシャル(認証情報)の入ったリクエストを送る

cf. Sending_a_request_with_credentials_included | Fetch 概説 | MDN

カスタムヘッダー

クロスオリジン・クレデンシャル以外にもcache, header, redirect, referrerリクエストのヘッダーのオプションが用意されています。

e.g. JSONで指定したヘッダー情報を追加

fetch(api_url, {
  header: {
    'Content-Type': 'application/json'
  }
}).then((res) => ... )

Header情報はHeaderインターフェースで色々と独自な設定が可能なようです。
cf. Headers | FetchAPI 概説 | MDN

対応ブラウザとPolyfill

fetchAPI - I can use
Can I use... Support tables for HTML5, CSS3, etc

この記事を書いた2019年1月時点では、IE11を含めたIEと、IE Mobile, Blackberry といった幾つかのモバイルブラウザで未対応をなっているようです。
Polyfillが用意されているのでこれらの非対応サポートブラウザで使用するにはこちらを利用するのが良さそうです。

Browser Support

babelしてみた

babel7で自動的にPolyfillがロードされる設定でFetchAPIが非対応ブラウザーようにバベれるか一応試してみました。

babel.config.js

const presets =  [
  ["@babel/preset-env", {
    "modules": false,
    "targets": ["ie > 10"],
    "useBuiltIns": "usage",
  }]
];
module.exports = { presets }

index.js

fetch('http://localhost:3000', {
  method: 'GET'
})
.then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.error(err));

👇$ yarn babel バベる

bandle.js

// 略
fetch('http://localhost:3000', {
  method: 'GET'
}).then(function (res) {
  return res.json();
}).then(function (data) {
  return console.log(data);
}).catch(function (err) {
  return console.error(err);
});

PromiseのPolyfillもロードされませんでした。
babel7デフォルトの@babel/preset-envではFetchAPIはPolyfillされないようです。
FetchAPIを使っているプロジェクトで非サポートブラウザ対応をする場合は配布されているPolyfillを使用するのが良さそうです。(babelで読み込ませられるのかな?)

感想

thenを二重にしないといけないのが最初ちょっとキモかったですがjQueryを使わない場合は、生JSのXMLHttpRequestで書くよりタイプ数も少なくて済むし見通しもよいので良さそうだと思いました。(生JS...


[参考]

[asin:B07L1GJZ1F:detail]

APIのモックアップに便利なjson-server使ってみた。

フロントエンドの制作とかで使えるAPIモックアップjson-serverってのが便利だよーって教えてもらったので使ってみた。

インストール

$ yarn add -D json-server

デフォルトのデータを作成

db.json

{
  "articles": [
    {"id": 1, "title": "json-server", "author": "TEST"},
    {"id": 2, "title": "aikatsu", "author": "Johnny"}
  ]
}

サーバーを起動するスクリプトを作成

packege.jsonjson-serverを起動するnpmスクリプトを作成 packege.json

{
  "scripts": {
    "start": "json-server --watch db.json --port 3001"
  }
}

--watchオプションを付けておくとサーバー起動中に直接db.jsonを編集しても変更内容を反映してくれるようになる。
(メインのアプリを3000で起動することが多いので、json-serverは3001番を指定しました。)

json-serverを起動

$ yarn start

  \{^_^}/ hi!

  Loading db.json
  Done

  Resources
  http://localhost:3001/articles

  Home
  http://localhost:3001

エンドポイントにアクセスしてデータを取得してみる

curlコマンドでDBにアクセスしてみます

$ curl -X GET http://localhost:3001/articles

👇

[
  {"id": 1, "title": "json-server", "author": "CHAIKA"},
  {"id": 2, "title": "aikatsu", "author": "Johnny"}
]

articlesのデータが返されました。

idで単一のデータを取得

データにidキーが有るとhttp://localhost:3001/articles/{id}でデータにアクセスできるようです。
cf. json-server#getting-started

$ curl -X GET http://localhost:3001/articles/2

👇

{"id": 2, "title": "aikatsu", "author": "Johnny"}

GETパラメータを使ってデータを取得

?{key}={value}のいわゆるGETで使われるパラメータ指定はフィルターになるようです。
cf. json-server#filter

$ curl -X GET http://localhost:3001/articles?title=json-servr

👇

[
  {"id": 1, "title": "json-server", "author": "CHAIKA"}
]

フィルターなので配列が返されました。

POST PUT DELETE

GET以外にもPOST, PUT, DELETEも受け付けます。
これらでデータを変更するとdb.jsonが直接変更されます。

POST
$ curl -X POST http://localhost:3001/articles/ -d 'title=foo&author=bar'
{
  "title": "foo",
  "author": "bar",
  "id": 3
}

idが自動的に割り振られてデータが挿入されました。
複数のデータがある場合はPOSTするデータを上記のように'で囲うか、-d title=foo -d author=barの様にデータごと-dオプションをで渡して上げる必要があります。-d title=foo&author=barのようにデータをコーテーションで囲わず送ると、先頭の値だけが受け付けられました。

PUT
$ curl -X PUT http://localhost:3001/articles/3 -d 'title=星宮いちご&author=星宮らいち'
{
  "title": "星宮いちご",
  "author": "星宮らいち",
  "id": 3
}

確認

$ curl -X GET http://localhost:3001/articles/

👇

[
  {"id": 1, "title": "json-server", "author": "CHAIKA"},
  {"id": 2, "title": "aikatsu", "author": "Johnny},
  {"title": "星いちご", "author": "星宮らいち", "id": 3}
]

※ 該当するidのデータがまるっとPUTで送ったデータに置き換えらる

$ curl -X PUT http://localhost:3001/articles/3 -d name=紫吹欄
{
  "name": "紫吹蘭",
  "id": 3
}
$ curl -X GET http://localhost:3001/articles/3

👇

{"name": "紫吹蘭", "id": 3}

もとのパラメータにマージされるわけではないので注意が必要かもです。 (PUTとしては正しい挙動?)

DELETE
$ curl -X DELETE http://localhost:3001/articles/3
{}

確認

$ curl -X GET http://localhost:3001/articles/

👇

[
  {"id": 1, "title": "json-server", "author": "CHAIKA"},
  {"id": 2, "title": "aikatsu", "author": "Johnny}
]

オンメモリで動作させる

jsonファイルを指定して動作させるとPOSTやDELETEでjsonファイルそのものが変更されてしまいますが、JSファイルを指定して実行した場合オンメモリとなりファイルの変更はされません。
公式ドキュメントには1000個のユーザーを作成するサンプルが載っています。cf. json-server#generate-random-data

db.js

module.exports = () => require('./db.json');

package.json

{
  "scripts": {
    "start-js": "json-server --watch db.js --port 3001"
  }
}

実行

$ yarn start-js

元のdb.jsonの内容はデフォルトデータとして利用され変更されることなくPOST, PUT, DELETEでデータが追加・変更・削除可能で、json-serverを走らせているプロセスが生きている限り変更した内容が保持されているようです。

[WIP] ネストしたデータを取得する方法が不明

例えば次のようなデータ

{
  "units": [
    {
      "id": 1,
      "name": "soleil",
      "members": [
        {"id": 1, "name": "星宮いちご", "division": "スターライト学園" },
        {"id": 2, "name": "霧矢あおい", "division": "スターライト学園" },
        {"id": 3, "name": "紫吹蘭", "division": "スターライト学園" }
      ]
    },
    {
      "id": 2,
      "name": "Luminas",
      "members": [
        {"id": 1, "name": "大空あかり", "division": "スターライト学園" },
        {"id": 2, "name": "氷川すみれ", "division": "スターライト学園" },
        {"id": 3, "name": "新条ひなき", "division": "スターライト学園" }
      ]
    },
    {
      "id": 3,
      "name": "WM",
      "members": [
        {"id": 1, "name": "神崎美月", "division": "LOVE MOONRISE" },
        {"id": 2, "name": "夏樹みくる", "division": "ナツキグリーニングガーデン" }
      ]
    }
  ]
}

soleilのデータは次のURLで取得できます。

http://localhost:3001/units/1

soleil内のmembersから星宮いちごちゃんを取得しようとして

$ curl -X GET http://localhost:3001/units/1/members/1
$ curl -X GET http://localhost:3001/units/1/members?name=星宮いちご

としてもデータを取得することが出来ませんでした。
アクセス方法が間違っているのか、そもそもネストしたデータを取れるようになっていないのかは深く調べていないので現状わかっていません。

所感

フラットなデータをやり取りするAPIjson-serverをインストールしてデータを用意するだけでサクッと作る事ができますので、Firebaseとか実際のサービスと繋ぐ前の開発用途にとても良さそうだと感じました。
ネストしたデータを取る方法がわからないままですが、GitHubのREADMEにはrouterの設定方法なども書いてあるので、自分で設定してしまえばネストしたデータとか複雑なデータでも返せるWEBAPIが作れるのではないかという気がしています。


[参考]

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

👆お正月に読みました。チーム・文化作りの本、アンチパターンも載っていて大変良かったです。
HRT心がけて生活していきたいです⭐

2018年に読んで良かったと思った本を5つ

あけましておめでとうございます。
Hyvää uutta vuotta!

私の夢は図書館のような部屋に住み本に埋もれて死ぬことです。
2018年に読んで良かったと思った本を5つ紹介したいと思います。
(普段プログラムのことが多いのでビジネス書的なのから順番に)

人生にゆとりを生み出す 知の整理術 - pha (思想・マインドセット)

人生にゆとりを生み出す 知の整理術

人生にゆとりを生み出す 知の整理術

知識を付け自分をアップデートしつづ付ける習慣をつけるためのテクニック集。

昨今、特にSNS等で知識がないことが強みのように振る舞う人を見かけるが、実際は知識があれば避けられる不幸があり知識があればより楽に生きることができる。
そして知識は誰も独占できない共有の財産ですべての人に平等に開かれているべきである。
楽にお金をかけずとも知識や情報に触れる習慣の付け方や、忘れっぽい未来の自分のためにblogやTwitterにアウトプットするテクニックなどが、小さな章ごとに別れて書かれているのでどこから読んでも大丈夫なようになっている。

人間は本来怠惰な生き物なので、習慣になってしまえば逆にその習慣を辞めることが難しい。そんな性質を利用して毎日少しでも興味ある部分を読んでみるのはどうだろうか?

1万円起業 - クリス・ギレボー (ビジネス書)

1万円起業 文庫版

1万円起業 文庫版

副業のすゝめ。

100$くらいの資金からビジネスを始めて成功した1500人へのインタビューを元に書かれた本。 起業するぞ!と息巻いて始めたというより、やってた事がビジネスになると気づいて起業したという感じの例が多い。
小さくとりあえず始めて見ること、小さく始めれば失敗してもダメージも少ないし方向転換も簡単だ。

やりたいこと・できること・求められていること を見極めることの大切さ、間違った方向の情熱だけではビジネスにならない。顧客には魚の釣り方を教えるのではなく魚を提供しよう。自分ではやってもないのに「そんなの無謀だ」とか「こうした方が良い」と助言してくる身内や友人の話は無視しよう。なぜなら彼らは実際には自分では何もやってないのだから。クレームを言ってくる人は何をやっても一定数いるから無視しよう。自分を安売りはするな。などなど名著「小さなチーム大きな仕事」でも書かれていたようなことも成功者のインタヴューとして出てくるので真理なのだと感じた。

本書を読むに当たって気をつけるべきは、紹介されている例の多くが英語圏での事である。ということだろう。
つまり、英語圏でビジネスをするという事は、日本人が日本語でビジネスを始めるより圧倒的にパイとなる人口が多いので、n%の人に刺さるサービスだとすれば当然母数が多いほうがビジネスとしては成功しやすい訳ですから。

放射線について考えよう。 - 多田将 (科学・テクノロジー・物理学)

放射線について考えよう。

放射線について考えよう。

イラスト描かせてもらってWEBサイト作らせてもらった作品なので自画自賛感がありますが、
イラストを描かせてもらうに当たって何度も本文を読み込み、放射線についての知識はもちろんだけど、何より自分で考えられるようになることの大切さ。定量的に、どの程度なのかと考えられるようになることの大切さ。を学ぶことが出来ました。

放射線についても、一つ一つ原理原則から段階を追って説明されており、イラストや例え話を使っていわゆる理系でなくとも理解しやすいように配慮された本になっていると思います!WEBサイトではフルカラーで全文公開されており、著者・出版社が正しい知識をもってもらえる事こそを目的としていることが伺えます。

放射線について、見えないからお化けのように怖がったままになるのではなく。正しい知識を付けてお化けを白日のもとに晒しましょう!
何より、解らないからといって自分で考えず誰かの意見を信じてしまうということは、騙されてしまっても仕方なく、それこそが危険な行為なのですから!!

アルキメデスのお風呂 - ニコ・ニコルソン (漫画)

アルキメデスのお風呂 1 (MFC)

アルキメデスのお風呂 1 (MFC)

科学的なことをがっつりした本や文章で読むのは苦手!という方には、ニコ・ニコルソン先生の新連載「アルキメデスのお風呂」がオススメ。

自分に自信のないぽっちゃり女子・原陽子が、王子様のような見た目の理系男子・大池学に一目惚れしたことから始まるラブコメディ。弁当屋で毎日、機械のように揚げ物を作っていた陽子は、ある日「私は誰にも必要とされてない」と思いつめて、駅で飛び込み自殺を図る。それを間一髪で止めたのが、通りがかりの大池だった。大池は茨城県東海村にある国営の研究施設で、素粒子物理学を研究する若き天才。陽子はひょんなことから研究施設の調理スタッフとして働くことになり、彼と運命の再会を果たす。
出典: 唐揚げ女子がニュートリノボーイに一目惚れ、理系ラブコメ「アルキメデスのお風呂」 - コミックナタリー

「病気や事故でなく、無知で死ぬのですか?」
ブコメ漫画を読んでいるだけで陽子の視点を通して、この世界を作っている小さな粒子の事やその研究のことを知ることができる。何よりマスコミや政治家がよく口にする基礎研究分野に対する「その研究って何の役に立つの?」に対する返答が描かれていることが素晴らしい。
加えて上記の「放射線について考えよう。」「宇宙のはじまり」の著者 多田将(高エネルギー加速器研究機構 素粒子原子核研究所 准教授。)による、わかりやすい用語解説コーナーも扉ごとにあり理解を深めることもできる。

銃・病原菌・鉄 - ジャレド・ダイアモンド (世界史)

今当たり前のように社会の中にある物事に対する"なぜ"(why)が色々と気になり始める本。

先史文明が誕生する以前、太古の人類は同じような生活を行っていたはずなのに、現代では大陸による富の差が生まれているのはぜだろうか?なぜ大陸や地域によって文明の発展に差が生まれたのだろうか?ヨーロッパが他の大陸を植民地にできるだけの力の差を得ることができたのは何故だろうか?
長らく人種による優劣のように語られてきた差が生じた原因を、人種や文明の優劣ではなく地学的な地域の特性から紐解いていく。
農耕が始まった地域に共通する特性、現代でも家畜化されている大型草食動物が羊・ヤギ・牛・豚・馬しかないことの理由、緯度経度による文化伝播の難易度の違い、集団生活が始まると疫病が発生するメカニズム、文字の発明とその伝播、家族単位・部族社会から国家・帝国が生まれる理由。

文化の発生と発展を原理から考えてみることで、現代社会に対して今までとは違った視点を持つことができるのではないだろうか。

青い星まで飛んでいけ - 小川 一水 (SF)

青い星まで飛んでいけ (ハヤカワ文庫JA)

青い星まで飛んでいけ (ハヤカワ文庫JA)

恋愛SF。ファーストコンタクトを集めた短編集。

本屋で偶然手にとった「コロロギ岳から木星トロヤへ」がたいへん好きな本で、失礼ながら作者については私自身の名前を覚えるのが苦手という理由もあって、それ以上作者の本を探すなどしていなかった事に気づき、この短編集を手にとった。

短編の多くは科学技術が進み人類が宇宙に進出している世界で主人公は電脳化されてたり人類によって創られたネットワーク化された自己修復機能を持つ機械群だったりする。そんな彼らが彼ら以外の存在とのファーストコンタクトを恋愛のように描いた物語。それらは電子信号の交換だったり、電子世界でシミュレートされた擬似戦争だったりするわけだけど…

正直SFってジャンルに詳しいわけではないのでSFとしてどうなのかという事は言えないけれど、読みながら死を失った生命の時間に対する概念や、脳の機能が電気信号なら自我はそこに宿るのか?電気信号化された世界では自己と他者の境界はどうなるのか?死の定義とは?と、ゴースト・イン・ザ・シェルの「現代の科学は未だに生命を定義することができない」という風な事を考えていた。
個人的に「守るべき肌」が好きだった。

プラス1冊 凍てつく海の向こうに - ルータ・セペティス (歴史小説)

凍てつく海のむこうに

凍てつく海のむこうに

原題『Salt to the Sea』

WW2末期ソ連軍が迫る今はない国東プロイセン。それぞれの秘密を抱えるリトアニア・東プロイセンポーランド・ドイツ4つの国出身の若者が国を脱出しようと海を目指す。物語はそれぞれの視点の語りで並行に進む。戦争に巻き込まれ戦争によって作られたそれぞれの秘密を徐々に明かしながら物語は進み脱出船ヴィルヘルム・グストロフ号で合流する。
実際にあったハンニバル作戦(ドイツ海軍が行った脱出作戦)、海事史上最大の犠牲者を出したヴィルヘルム・グストロフ号撃沈事件を下書きにした戦争に引きずり込まれた若者たちの小説。

私自身、欧州の歴史特に大戦期の北欧諸国の歴史に興味があり趣味で調べているので、ドイツ帝国のもととなったプロイセンソ連・ドイツに占領され、さらにソ連に再占領されたリトアニアポーランド、そしてドイツの少年兵と歴史には残らないし、個人では到底抗うこと出来ず戦争に巻き込まれた個人による、国家の言い分ではなく彼ら個人の見えているものを主体とした物語は映画を観ているようでたいへん興味深かった。

そして、原題「Salt to the Sea」はキリスト教的な概念で多くの日本人には馴染みがないだろうから、美しい邦題を新しくつけてくれたこと、巻頭表紙裏に物語が始まった際の国境線のある地図、巻末表紙裏は現在の国境線のある地図になっていて、物語が過去の終わったものではなく現在にも地続きであることを強く意識させる演出になっている装丁もたいへん素晴らしい本。

 

読んだ本はだいたい読書メーターにメモを取るようにしていおり、ここに上げたものはほぼそこからの焼き増しです。
この読書メーター良かった部分や気になった部分を書いておくだけで、結構記憶に残るので大変良いです。(映画メーターってのもあったのですがいつの間にかサービス終了して消えてました...)
 

去年1年を振り返ったポエム

昨年は10月から都会に半復帰しました。
都会は田舎ちほーと違って公共交通機関が発達しているので、電車で移動中にたくさん本を読めるので大変良いです。(同じ移動でも車の運転時間に取られるのとでは圧倒的にインプットできる時間の差が生まれると思います)
また、商業のイラストのお仕事を初めてさせてもらったり、compass漁って毎日のように勉強会に参加したり、工数3ヶ月確保しておいた案件が半年リスケになって貧困ライフを満喫することになったり波乱に満ちた1年でした。

2019年は技術向上と生活の安定。それから、ここ数年間繰り返されてた短納期・低報酬なお仕事のループで疲れ果ててあれだけ楽しかったデザインやお絵かきが苦痛になってしまっていたので、少しづづリハビリして楽しい習慣化できるようにしたいです。
心が死ぬとはまさに

かつてあれほどまで真剣で切実だった想いが綺麗に失われている事に気付きもう限界だと知った
新海誠秒速5センチメートル」 より引用

ということなのです。


ベルリンは晴れているか (単行本)

ベルリンは晴れているか (単行本)