Postman v10 が発表された
Postman v10 のリリースが発表されました。 https://blog.postman.com/announcing-postman-v10/
面白そうなアップデートが結構あったので、内容を簡単にまとめてみます。
Postman CLI
- Postman と同じランタイムで実行される。
- Newman の基盤の上に乗っている。
- https://blog.postman.com/introducing-the-postman-cli-to-automate-your-api-testing/
自動APIテストとかに使えるかも。
gRPC サポート
- GraphQL に続き gRPC がサポートされた。
- gRPC のURLをURLバーに打ち込むだけで、使えるメソッドをセットしてくれる。
- サーバーリフレクションというらしいんだけど、サーバーに問い合わせて使えるメソッドを取得しているのかな?
- https://blog.postman.com/postman-v10-and-grpc-what-you-can-do/
重い腰を上げて gRPC を始める機が熟したか...。
パートナーワークスペース
- チーム外のメンバーを招待できるようになった。
- 権限を絞ったり、特定のワークスペースにのみアクセスを許可するなどの制御ができる。
- これらを管理する新しいロールができた。
- https://blog.postman.com/introducing-partner-workspaces/
「チームに入れるとコストが気になるけど、同じワークスペースは使ってほしい業務委託メンバーが複数人いる」みたいなケースで嬉しいかな?
API Security
- セキュリティルールに違反してしないかをチェックできる。
- 定義だけじゃなくてリクエストもチェックしてくれる。
- Postman が提供してくれるルールをON/OFFして設定する。
- https://blog.postman.com/introducing-api-security-in-postman-v10/
API 定義のレビューってミスを見逃しがちな気がするから良いかも。 というかそもそも脆弱な定義とか全然知らないからこれを使って学んでいきたい。
API Governance
- 組織の API のルールに違反してしないかをチェックできる。
- 重大度とかも設定できる。
- Postman rule library に含まれる違反の場合は影響や修正方法へのリンクを掲示してくれる。
- https://blog.postman.com/api-governance-with-postman-v10/
スタイルガイドがきちんとある組織ならかなり活きそう。 スタイルガイド作るのが大変そうだけど。
まとめ
Postman はAPIサーバーの動作確認くらい使い方しかしたことなかったんですが、かなり多機能なので気になったものは使ってみようと思いました。
あたりも紹介あったけど、こちらは全く使用イメージが湧きませんでしたね...。
Goで文字幅操作
golang.org/x/text/width
パッケージはテキストの文字列の操作ができる。
全角に変換
s := "ハンカクカラゼンカク" w := width.Widen.String(s) fmt.Println(s) fmt.Println(w) // output: // ハンカクカラゼンカク // ハンカクカラゼンカク
s := "モトモトゼンカク" w := width.Widen.String(s) fmt.Println(s) fmt.Println(w)
output: モトモトゼンカク モトモトゼンカク
全角を引数にwidth.Widen.String()を実行しても全角のままである。
半角に変換
s := "ゼンカクカラハンカク" h := width.Narrow.String(s) fmt.Println(s) fmt.Println(h)
output: ゼンカクカラハンカク ゼンカクカラハンカク
濁点が変換されない。
解決策を紹介している記事を見つけた。
これを解消するには,安直な手段だが,いったん NFD 正規化で合成列に変換してから変換するとよい。
s := "ゼンカクカラハンカク" h := width.Narrow.String(norm.NFD.String(s)) fmt.Println(s) fmt.Println(h)
output: ゼンカクカラハンカク ゼンカクカラハンカク
NFD 正規化については後からちゃんと調べよう。
正規の幅に変換
s := "カタカナabc" f := width.Fold.String(s) fmt.Println(s) fmt.Println(f)
output: カタカナabc カタカナabc
所感
文字コードちゃんと勉強する。
base64のまとめ
base64とはすべてのデータをアルファベット(a-z,A-Z)と数字(0~9)、一部の記号(+,/)で表す変換方式である。 データの長さを揃えるのに、空白に詰める無意味なデータ(パディング)として=を使用する。 URLや正規表現の中では+,-は特別な意味を持つことがあるので-,_が用いられることもある。
電子メールをやりとりするプロトコルのSMTPでは、ASCIIという7bitで表現される英数字しか送受信できなかった。 つまり画像や音声、バイナリデータの送受信はできなかった。 MIME(Multipurpose Internet Mail Extensions)という規格が登場し、その中でbase64が定められた。 MIMEに則ってエンコード、デコードすることで画像や音声、バイナリデータの送受信可能となった。
変換方法まとめ
GoでPythonのlambdaっぽいプログラムを書いた
を読んでGoならどうやって書けるかなーと気になったので書いてみた。
package main func double(n int) int { return n * 2 } func main() { lambda := func(n int) int { return n * 2 } print(double(2) == lambda(2)) // true }
結論、Goでも割とシンプルに書けました。
GraphQLのN+1問題に向き合う ~問題提起編~
はじめに
GraphQLを扱うデメリットとしてN+1問題が挙げられる。
なぜGraphQLだとN+1問題が起こってしまうのか考える。
そもそもN+1問題とは
そもそもN+1問題とはなにか。
N件のデータと、取得したそれぞれのデータに紐付くデータを取得する際に、DBへN+1回のアクセスが生じる問題のことをN+1問題という。
<例>
ここに一つのブログシステムがある。扱うDBはRDBであり、ブログ投稿記事テーブル、ユーザテーブルの二つのテーブルでデータを管理する。
ブログ投稿記事一覧ページを表示する際に10件のブログ投稿記事を取得し、それぞれの記事の作者であるユーザも取得したい。このとき、ブログ記事はユーザのIDを持っており、そのユーザのIDを基にユーザの情報を取得する。
このような構成の場合、ブログ投稿記事一覧を取得するためのアクセス(1回)と、取得したそれぞれのブログ投稿記事に紐付くユーザを取得するためのアクセス(N回)が生じる。解消方法としては、JOIN句で一回のアクセスで取得してしまう、もしくは取得したブログ投稿記事が持つユーザIDを持つユーザだけを取得するSQLを作成して二回のアクセスで取得する。
以下の記事がわかりやすいと思う。
なぜGraphQLで問題視されるのか
上記の方法で取得すればなんの問題もないはずだが、なぜGraphQLで問題視されるのか。
気になって調べてみると二つの理由があった。
紐付いたリゾルバー切り出してしまった時の問題
こちらに関しては柔軟にしたばかりに、N+1問題が起きてしまったパターン。
どういうことかというと、GraphQLではリクエスト次第ではユーザ情報を含めないようレスポンスを要求することも可能なので、フィールド指定でユーザの情報が呼ばれた時にだけ、ユーザを取得するためのリゾルバが呼ばれるように切り出すことがある。確かにこの切り分けは便利で要求された時のみDBアクセスが走るのでパフォーマンスが良い。
だけども要求された時には毎回、内部でリゾルバーが呼び出されてN+1問題が生じるという話。
毎回網羅的に取得するようにしてしまったときの問題
かといって毎回、JOINなりEager Loadingするとフィールドが要求されていないにときにも、毎回紐付くデータまで取得してしまう。
要求されていないデータまで取得されてしまうことでパフォーマンスの劣化も考えられるという話。
解決策
DataLoaderを使うといいらしい。。。
そのうちまとめよう。
ページングのソートで気をつけること
バックエンドの実装で、ページングしたデータを返す際の話。
基本ライブラリに頼っているのであまり実装のことを考えたことがなかったので、結構苦戦した。
以下のような数字を降順で並べたリストのデータを、ページングでフロントエンドに返すとする。
7,6,5,4,3,2,1,0
ページごとの件数が3だとすると、1ページ目は7,6,5
、2ページ目は4,3,2
となる。
このときSQLを用いたデータベースへのアクセスだが、1ページ目から2ページ目の遷移は簡単で端っこの値を基に比較演算子を用いる。(5 > X)
3ページ目から2ページ目への遷移はどうだろう。
1,0
から4,3,2
を取得したい。
このときのポイントとして、全体の並び順が降順であってもDBから取得する際に並べ替えてからLIMITで件数を試ぼってはいけない。
1
より大きい値を降順で3件欲しいわけだが、単純に1
より大きい値を降順で3件要求すると取得できる値は7,6,5
となってしまう。
要するにASCで3件取得した後にDESCで並べ替えなければいけないのだ。
ちなみに昇順でも同じように、前ページを取得する際には取得後の並べ替えでないといけない。
0,1,2,3,4,5,6,7
0,1,2
->3,4,5
ASCで取得可能
6,7
->3,4,5
DESCで3件取得した後にASCで並べ替え
きっとすぐに忘れるので、ちょっとでも考えるヒントになるように備忘録として残しておく。