自社のサービスではOpenAPIを使ってサーバーを書いています。
https://swagger.io/specification/
ほぼ全てのエンドポイントに影響のあるリファクタリングをした時に、動作確認が辛すぎたのでインテグレーションテストを書くことにしました。
できたものは以下になります。
integration-test/integration_test at main · yutakahashi114/integration-test
Contribute to yutakahashi114/integration-test development by creating an
account
on GitHub.GitHubyutakahashi114
[https://github.com/yutakahashi114/integration-test/tree/main/integration_test]
以下、簡単に説明を書いていきます。
サンプルアプリケーション
以下のschemaを元にサーバーを実装します。ユーザーの一覧取得、ID指定の取得、登録、更gomockでスライスを順不同で一致させるためにMatcherを自作しました。
※追記
v1.6.0 から InAnyOrder というMatcherが用意されているので、不要になりました。
gomock package - github.com/golang/mock/gomock - pkg.go.devGo
[https://pkg.go.dev/github.com/golang/mock/gomock#InAnyOrder]gomock
GolangでUTを書く際に使います。
GitHub - golang/mock: GoMock is a mocking framework for the Go programming
language.GoMock is a mocking framework for the Go programming language. -
GitHub
- golang/mock: GoMock is a mocking framework for the Go programming language.
GitHubgolang [htt自分が関わっているサービスで、認証にAmazon Cognitoを使っています。
Amazon Cognito(ウェブ/モバイルアプリのユーザー管理)| AWSAmazon Web Services, Inc.
[https://aws.amazon.com/jp/cognito/]
全てのリクエストについてトークンの検証をするので、APIサーバの動作確認時に必ずヘッダにトークンをセットする必要があります。このトークンを用意するのが地味に面倒だったので、Golangでスクリプトを書きました。
以下の記事を参考にしました。
golangでCognito認証(ただしSecure Remote Password(SRP)プロトコルではない) - Qiita参考
http://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.ht...
Qiitacobachan [https://qiita.com/cobachan/items/9e自分が関わっているサービスで、認証に Amazon Cognito を使っています。
Amazon Cognito(ウェブ/モバイルアプリのユーザー管理)| AWSAmazon Web Services, Inc.
[https://aws.amazon.com/jp/cognito/]Cognito
は公式でエミュレータ的なものは提供されていないようなので、ローカル環境では開発用の Cognito に繋いでいます。
実物の Cognito を使う場合、メールをモックサーバに飛ばせないので誤送信の可能性があったり、ユーザーの追加が面倒だったりと、個人的に不便を感じていました。
そのため、Cognito の動きを再現するエミュレータを作りました。
今回は自分が必要な最低限の機能だけ実装しています。足りない機能は適宜追加するつもりです。
とりあえず以下の機能を実装しました。
* 公開鍵の取得
* 認証
* ユーザー作成
エンドポイント
Cognito のエンドポイントは恐らく以下の2つだけです。
1. GET https://cognito-idp.{region}.XormのBulk Insert(一括登録)で、件数が多い場合に遅くなったので色々試して速くしました。
過去にもXormの記事を書いているので、よろしければどうぞ。
GolangのORM、Xormの使い方ざっくりまとめ
最近、GolangのORMとしてXormを使っています。GoのORMといえばGormが主流で、調べてもXormに関する記事が少なかったので、備忘録としてまとめてみました。
自分が業務で使用している機能のみをまとめたので、さらに詳しく知りたい場合は公式ドキュメントを参照ください。 環境 * Go : 1.13.1 * Xorm :
0.7.9 * PostgreSQL : 11.6 使用するテーブルcreate table users( id BIGSERIAL, first_name
VARCHAR(20) NOT NULL, last_nameVARCHAR(20) NOT …Anti-Pattern Inc. Engineering
BlogYu Takahashi [https://tech.anti-pattern.co.jp/xorm/]
Xormで複雑な以前、基本的な使い方をまとめた記事を書きましたが、もう少し複雑なことをしたくなって色々試したので、まとめておきます。
GolangのORM、Xormの使い方ざっくりまとめ
最近、GolangのORMとしてXormを使っています。GoのORMといえばGormが主流で、調べてもXormに関する記事が少なかったので、備忘録としてまとめてみました。
自分が業務で使用している機能のみをまとめたので、さらに詳しく知りたい場合は公式ドキュメントを参照ください。 環境 * Go : 1.13.1 * Xorm :
0.7.9 * PostgreSQL : 11.6 使用するテーブルcreate table users( id BIGSERIAL, first_name
VARCHAR(20) NOT NULL, last_nameVARCHAR(20) NOT …Anti-Pattern Inc. Engineering
BlogYu Takahashi [https://tech.anti-pattern.co.jp/xorm/]環境
* Go : 1.15.8
* Xorm : 1.0.7
パフォーマンス改善のために、今までアプリでやっていた処理をDBに寄せることになりした。その一環でSQLで配列を使った処理を書いたので、まとめました。
詳しくは公式ドキュメントを参照ください。
9.18. 配列関数と演算子 [https://www.postgresql.jp/document/11/html/functions-array.html]
環境
* PostgreSQL 11.6
使用するテーブル
create table users( id BIGSERIAL, first_name VARCHAR(20) NOT NULL, last_name
VARCHAR(20) NOT NULL, first_name_kana VARCHAR(20), last_name_kana VARCHAR(20),
version BIGINT NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT
CURRENT_TIMESTAMP, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMEstructとmapの相互変換
任意のstructをHashMapに変換する必要があったのでderive macroで実装しました。
できたものは以下になります。
GitHub - yutakahashi114/rust-map-macroContribute to
yutakahashi114/rust-map-macro development by creating an account on GitHub.
GitHubyutakahashi114 [https://github.com/yutakahashi114/rust-map-macro]
Rustにはreflectionがない
Rustは構造体からmap(HashMap)へ変換するための機能がないらしいです。
例えばGolangでは以下のように reflect パッケージを使うと実装できます。
Go言語でstructからmapへ変換 - Qiita構造体のフィールド一覧を取得したくなったので、reflectを使って実装。
struct2map.gopackage main import ( “fmt” “re結論
1つのcollectionに大量のdocumentを一括書き込みする際、500件のバッチ書き込みを20並列で実行したところ、以下の時間で完了した。
Firestoreの書き込み制限
Firestoreは書き込み時にいくつかの制限があります。詳しくは
https://firebase.google.com/docs/firestore/quotas
[https://firebase.google.com/docs/firestore/quotas?hl=ja] にあります。
今回気になったのは4番目の制限です。ある条件下では1つのcollectionに対するdocumentの書き込みは 1秒間に500件が上限、という事です。
※2022/05/11 追記
制限について、以下のように変更されていました。「できなくは無いがパフォーマンスが悪くなるかも」という閾値のようです。
あるシステムのパフォーマンス調査をしていて、この上限のせいで遅くなってるかも?という話になりました。書き込み速度について調べていると以下の記事を見つけました。
Firestoreに負荷試験(L結論
単一documentを連続で読み込むと、約 300/s 程度の速度は出せそう。
読み込み速度
前回は書き込み速度を測定
[https://medium.com/anti-pattern-engineering/firestore%E3%81%AE%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E9%80%9F%E5%BA%A6%E3%81%AE%E6%A4%9C%E8%A8%BC-8e1d4595a701]
しましたが、今回は読み込み速度を調べました。
環境
* Google Compute Engine、e2-medium (2 vCPU、4GB メモリ)
* Ubuntu 20.04 LTS
* Docker 19.03.8
* Golang 1.14.9
* cloud.google.com/go/firestore 1.3.0
検証
単一のdocumentを、1秒毎に指定したrateの数だけ取得し、全ての取得処理が完了するまでの時間を測定します。これを指定した回数(今回は60回)繰り返しました。使用したコードは以下です。(creacannot move out of a shared reference
Rust初心者です。上記のエラーでハマりました。
vectorの要素のうち指定したindexの値だけを取り出したい
Goでいうと以下のような処理です。
func get() Hoge {
vector := []Hoge{{name: "first"}}
return vector[0]
}
type Hoge struct {
name string
}
まあ普通にできます。Rustでこれと似たようなことをするとき、最初に以下のようなコード書きました。
fn get() -> Result<Hoge, String> {
let vector: Vec<Hoge> = vec![Hoge {
name: String::from("first"),
}];
if let Some(&first) = vector.get(0) {
return Ok(first);
Firestore Local Emulator にimport/export機能が追加されたらしいので、それを利用して擬似的に永続化しました。
Dockerを落とすたびにリセットされるデータ
最近、業務でFirestoreを使用した開発をしています。ローカルではエミュレータを起動し、それに接続しています。このエミュレータには個人的に不便なことがあり、データをメモリ上に保存しています。ローカルの開発にはDockerを使用しており、エミュレータもDocker上で動かしています。そのため、Dockerを落とすたびにデータが全消去されてしまいます。
何とかしたいなーと思いつつもいい方法が見つからず放置していましたが、少し前にこちらの記事を見つけ、最近import/export機能が実装されたことを知りました。
Firestore エミュレータのデータをローカル環境で import/export する - Qiita概要 Firebase エミュレータで
Firestore の import/export
ができるようになったので、導入方法について紹介します。これまで、エミュレータを再起