Posts for: #Go

結合テストのリファクタリング

0時に寝て7時に起きた。前日は久しぶりに飲んでいい気分で寝てた。朝コンビニ寄ったらいつもほぼ満席のイートインが閑散としているなと思いつつ、オフィスへ行って始業報告して、今日祝日だよとツッコミもらった。全然気付いていなかった。まだ新しい天皇誕生日に慣れてない。

go のテストにおける setup/teardown 関数の実装

昨日から結合テストのリファクタリングをしていてせっかくオフィスに行ったので続きをする。結合テストだとデータを作ったり削除したりをテスト単位にやりたい。例えば、ユーザーを作成してテスト実行し、終わったら作成したユーザーを削除したい。次のように setup 関数を書き、返り値として teardown の関数を返す。このときに t.Helper() を呼び出しておくと、エラーがあったときにどの呼び出し元のテストでエラーが発生したかがわかる。

func setupUsers(t *testing.T, users []mongodb.User) func() {
	t.Helper()
	user := mongodb.NewUserCollection(url, username, password)
	for _, u := range users {
		if err := user.Save(u.ID, u.Attributes); err != nil {
			t.Fatalf("failed to create a user: %s", err)
		}
	}
	return func() {
		t.Helper()
		if err := user.Truncate(); err != nil {
			t.Fatalf("failed to truncate the user collection: %s", err)
		}
	}
}

使い方は簡単で setup 関数を呼び出すと teardown 関数が返ってくるのでそれを defer で呼び出すとよい。

teardown := setupUsers(t, usersTestData)
defer teardown()

しかし、この setup 関数をサブテストと一緒に並行実行すると意図したように動かない。どうやらサブテストを並行実行すると親テストが呼ばれた後に呼び出されるという仕組みになっていて、サブテストを実行する前に teardown が呼ばれてしまうので意図した制御にならない。How to handle parent test teardown with parallel subtests in golang の回答 によると、サブテストからさらにサブテストを実行するとよいとある。この場合、親テストとサブテストは同期的に実行され、サブテストの中でさらにサブテストを並行実行するという考え方で意図した振る舞いになる。並行実行するときは次のようなコードになる。

func TestMy(t *testing.T) {
    tests := []struct{
        // test cases
    }

	teardown := setupUsers(t, usersTestData)
	defer teardown()

	t.Run("wrap for setup process", func(t *testing.T) {
		for _, tt := range tests {
			tt := tt
			t.Run(tt.name, func(t *testing.T) {
				t.Parallel()
                // do test
            })
        }
    })
}

コンテキストによるキャンセル処理

1時に寝て7時に起きた。昨日がっつりコードを書いていたせいか、起きてから今日は休みたいと思いながらだらだらしてた。休めないのだけど。貧乏暇なし。

echo のリクエストコンテキスト

昨日の続きで mongodb のリファクタリングをしている。mongodb はほぼすべての処理で コンテキスト を受け取れるように設計されている。メンバーが go の context の扱いを理解していないのでコンテキストを渡すようなインターフェースになっていない。私もこれまでのコードレビューでキャンセル処理は些事なのでそれよりも機能開発を優先して後回しにしていた。それで、いま機能が一通り開発完了したのでインターフェースにコンテキストを受け取るようにリファクタリングした。デフォルトのコンテキストとして echo のリクエストコンテキストを渡す。Canceling request #1815 によると、echo のリクエストコンテキストは次の状況のときにキャンセルしてくれる。

  • クライアントのコネクションがクローズされたとき
  • http2 でリクエストがキャンセルされたとき
  • ServeHTTP() が返るとき
    • サーバーがシャットダウンするタイミング?

使い方はこんなイメージ。

ctx := c.Request().Context()
store := c.Get(myStore).(Store)
store.Get(ctx, request.From, request.To)

余裕がなさ過ぎる

1時に寝て7時に起きた。タスクが溜まり過ぎてそろそろ辛くなってきているところ。この余裕の無さはよくないことなので、自分のダメさ加減というか、大いに反省しないといけない。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。いつもは打ち合わせの議題を2-3日前には共有するようにしている。だいたい水曜日前後に議題のリファレンスをはらさんに共有して金曜日の朝に話している。しかし、今週はリファクタリングに集中し過ぎていて前日の寝る前になって議題を共有していないことに気付いた。そして朝起きてから急ぎで議題を考えて共有していた。これはとてもよくない。準備ができていないので今日の議題は主に近況の話しをしていた。

ハドルの雑談

先日から 午前中はハドルに滞在 するようにしている。今週は木曜日にチーム外から勉強会についての相談が、今日はメンバーから気分転換に雑談にやってきてくれた。おそらく私がハドルにいなかったらゼロだったコミュニケーションの機会が、1週間に1-2回でもあることに私は嬉しく思ってしまう。フルリモートワークにおける、オフラインのような気軽な雑談の機会を提供する施策の1つとして意味なくハドルに入るのは悪くない気がしている。そのときにコミュニケーションを強制させるような押し付けが発生しないよう、運用ルールを徹底することが大事に思える。いまは相手がハドルに入ってくると 1on1 のような雰囲気になってしまうのでその次の挑戦としてはハドルに入っていても話さなくてよいといった運用ルールを設ければよいのではないかと思う。例えば、午前中はとりあえずハドルに入って気分が向いたときだけ話しかけるみたいな、ゆるいコミュニケーションの場になればいいなと思う。

ハドル雑談の運用ルールのアイディア

  • ハドルに入らなくても業務上の支障は一切おきない
  • ハドルにいる人には、用事があってもなくても、話しかけてよい
  • ハドルに入っていても話さず聞いているだけでもよい
  • 業務に集中していて忙しいときは話しかけられても後回しにしてもよい (ハドルから退出した方がわかりやすいかもしれない)

go の generics 勉強会

ちょうど先週からあちこち直したり、mongodb のクライアント周りをリファクタリングしたりしている。その過程で generics を使ってコードの共通化もしたりしている。私自身 generics で意図した通りにコンパイルできなくてはまってしまった事例もあるのでそういった失敗コードも共有した。go の generics はコードに対して静的な領域しか適用されず、コード中における動的な値の型は generics とは直行した概念だというところに初学者ははまるのではないかと思う。私がはまった。参加者におそらく1度はまるからはまったときに私が話していたことを思い出してとコードの解説をしていた。

余裕があったらスライドにまとめて後で資料として再利用できるようにしたかったものの、私の作業に余裕がなさ過ぎて次のリファレンスから引用しながら解説するといった勉強会になった。ただ私が読んでよいと思った他者のスライドやブログの記事のみを紹介している。それはそれで参考にはなるので勉強会の意図としては問題なかったんじゃないかとは思う。

windows の調査を開始

1時に寝て7時過ぎに起きた。やや飲み過ぎて、2日酔いではないけど起きたときは気分が悪かった。

go-winio を触ってみた

windows 向けのモジュールを作り直すにあたり、有識者のサポートをお願いしているものの、私も最低限の知識はないとあかんやろと調査を開始した。microsoft/go-winio というライブラリが ms 社のリポジトリで公開されている。公式ならよいのだろうと安易に考えて触ってみたものの、ドキュメントがほとんどなくて、まず使い方がわからん。いまのところ、windows に詳しい人向けのライブラリみたい。ひとまずリポジトリにある pipe_test.go のテストコードを読みながら名前付きパイプを介したプロセス間通信をやってみた。一応は動いたのでここから内部の windows api の仕様や設定などをみていく。その過程で go-winio のチュートリアルがないのであれば、私がテックブログを書いてもよいのかもしれない。

チュートリアル的に書いてみたコードは次の通り。

課題管理勉強会

出張のときに毎月の課題管理勉強会。とくにネタが思いつかなかったので エンジニアリング組織論への招待 を題材にしてみた。資料はすでに作ってあった 。私にとっては課題管理をやる意義や価値の大半がこの書籍の中で解説されている。用語や考え方のところでとても参考になるし、いまメンタリングの技術の章を読み直したりもしている。昔はマネージャーやってなかったからその章は読み飛ばしてた。開発組織向けの組織論を解説した書籍でこれ以上のものは、いまのところ、私が読んだ本の中では知らない。4年前に読んだ本を、今回の勉強会を開く機会でまた読み直すきっかけにもなってよかった。本はコンテキストがきれいに構成されているので他の人の所感や意見を聞いたり雑談したりする題材としてもよさそうに思える。

集中のち寝不足

1時に帰ってきてそのまま寝ないで6時10分の新幹線に乗ってから2時間半ほど寝た。これはこれで時間の使い方が有意義な気がする。午前中は翌日の定例会議の準備を着々と進めて、ci/cd 環境の改善、午後からリファクタリングなどをやっていた。15時をまわると眠くなってきて散歩したりして気分転換しつつも体調悪いなと思って17時半にお仕事を終えてホテルへ戻って2-3時間ほど寝てた。その後、晩ご飯食べるかなと出掛けたものの、あまり食欲もなくて、2時間ほど付近を散歩して運動していた。たまにはそういうのもいいか。飲食店が多い地域なので外から眺めているだけでもわりと楽しい。

ssh 経由のデプロイ

これまで ci/cd でテストして docker イメージをビルドしてコンテナレジストリに登録するところまでやっていた。実際にテスト環境にデプロイするときは、テスト環境にログインして更新用のスクリプトを私が手動実行していた。そんなに頻繁にテスト環境を更新する必要がなかったのでそれでも十分ではあるものの、ci/cd の完成形を目指すなら自動化すべきという考え方もあってデプロイの部分を作ることにした。

もっとも簡単な方法として Using SSH keys with GitLab CI/CD をみながら、ssh でテスト環境にデプロイすることにした。すでに更新用のスクリプトがあって、テスト環境にログインして実行すればできる状態なので ssh さえ使えればすぐに移行できるという話しでもある。openssh-client を使うためにベースイメージを alpine から ubuntu にしてパッケージをインストールしないといけない。実行時間がややかかるというコスト以外には気にならないかな。ssh の秘密鍵を file 種別でもつのか通常の環境変数でもつのかで扱いが異なって、それに少しはまったぐらいですぐできた。今後は docker イメージのビルド単位に自動的にデプロイされるようになる。

interface{} の型エイリアスとしての any

go のコードをリファクタリングしていて json.Marshal の引数が any となっていることに気付いた。

func Marshal(v any) ([]byte, error) {
    ...
}

go 1.18 以降で interface{} の型エイリアスとして any が定義されているらしい。任意の型を扱えるシグネチャとして、メソッドの振る舞いのみを規定する interface{} を使うというのは型システムとしては正しい。他言語でいえば object に相当するものが go はオブジェクト指向言語ではないのでそれがない。そういう間違っていないけど、わかりにくいなと思っていたものに any という名前の型エイリアスが導入されてとてもしっくりきた。プログラミングしていて、実務的にどうかというところをちゃんと改善していくところがみえるのは楽しい。

type any = interface{}

go の学び直し 静的解析編

23時に寝て2時に起きて5時ぐらいにも起きて7時に起きた。昨日は podcast 収録でたくさん話して疲れてしまってそのまま帰ってすぐ寝た。すぐ起きるんだけど。

ストレッチ

今日の開脚幅は開始前157cmで、ストレッチ後159cmだった。朝出かける前に開脚のストレッチしたら数値よくなるかな?と思ってやってみたらいつもより少しよくなった。ストレッチはいつも通りとも言えるし、腰の張りがまだまだ残っていることも確認できた。疲労が溜まっているんよな。毎週ストレッチしているからこの程度の疲労で済んでいるとも思える。お正月に実家から戻ってきてから1月の東京出張と35日は終えた。来週はまた2月の東京出張とその週末に49日がある。ここまで体力がもてばその次の法要は初盆なので少し空く。体力的に第4四半期の山場と言えるかもしれない。ただがんばる。

go の学び直し

Gopher塾 #3 - 静的解析を使ったGoの開発ツール制作 入門編 - DAY 1 に参加した。

過去にも Python とマクロ、インポートフックと抽象構文木Java のアノテーションプロセッサを試す など、メタプログラミングのアプローチやコード生成などを実務で使ってきたので静的解析にも関心がある。講義内容の詳細は書かないけど、静的解析のような難しい話題に対して4時間という短い時間でとてもよい講義になっていたと思う。go の静的解析の要点や提供されているツールなどを一通り学ぶことができた。もちろん、実用するには試行錯誤や習熟を必要とするけど、取っ掛かりとして十分な内容に思えた。

skeleton というツールを使って静的解析のための analyzer プロジェクトのひな形を作る。

$ go install github.com/gostaticanalysis/skeleton/v2@latest
$ skeleton myanalyzer
$ tree myanalyzer
myanalyzer
├── cmd
│   └── myanalyzer
│       └── main.go
├── go.mod
├── myanalyzer.go
├── myanalyzer_test.go
└── testdata
    └── src
        └── a
            ├── a.go
            └── go.mod

意図的にテストが落ちるようになっていてすぐ動作確認できる。

$ go mod tidy
$ go test                                          
--- FAIL: TestAnalyzer (0.05s)
    analysistest.go:448: a/a.go:5:6: diagnostic "identifier is gopher" does not match pattern "pattern"
    analysistest.go:512: a/a.go:5: no diagnostic was reported matching "pattern"
FAIL
exit status 1
FAIL	myanalyzer	0.349s

いろいろ説明を端折るけど、試しに FuncDecl の ast ノードに対して関数の行数をカウントする処理を実装してみた。analysis パッケージの Pass を使うと便利なユーティリティが提供されていて、静的解析をするときに面倒な処理をショートカットできて簡単に実装できることが理解できた。ここで作った analyzer は go vet で実行できるそうなのでプロジェクトの独自ルールを analyzer で実装して ci でチェックするといった運用もできる。応用範囲は広そう。

case *ast.FuncDecl:
	fmt.Println(n.Name, n.Pos(), n.End())
	start := pass.Fset.Position(n.Pos()).Line
	end := pass.Fset.Position(n.End()).Line
	fmt.Println("the number of lines:", end-start)

pure go の javascript 処理系を使ってみた

23時に寝て2時に起きてだらだらして寝て7時に起きた。テンカイチ 日本最強武芸者決定戦 という漫画を読んでた。

pure go の javascript 処理系

ユーザー定義スクリプトを実行する要件がある。システム管理者がスクリプトを書くなら javascript がいいかなと次のリファレンスを調べたりしていた。

これらを読んだ結果として dop251/goja がよいだろうと判断した。README だけ読めばすぐに実装できてめっちゃ簡単で感心した。こういうライブラリを私も会社のプロダクトとして作ってみたい。万人が使うものではなくても、必要なときがたまにあって、すごく使いやすいみたいな。こんな感じで goja の機能を使ってライブラリ実装してみた。

type FunctionCaller func(funcName string, args ...interface{}) (interface{}, error)

func NewFunctionCaller(script string) (FunctionCaller, error) {
	vm := goja.New()
	_, err := vm.RunString(script)
	if err != nil {
		return nil, err
	}
	return func(funcName string, args ...interface{}) (interface{}, error) {
		f, ok := goja.AssertFunction(vm.Get(funcName))
		if !ok {
			return nil, fmt.Errorf("failed to get function: %s", funcName)
		}

		funcArgs := make([]goja.Value, 0, len(args))
		for _, arg := range args {
			funcArgs = append(funcArgs, vm.ToValue(arg))
		}
		value, err := f(goja.Undefined(), funcArgs...)
		if err != nil {
			return nil, fmt.Errorf("failed to call javascript function: %w", err)
		}
		return value.Export(), nil
	}, nil
}

Is it goroutine-safe? によると、goroutine-safe ではないので毎回 js の runtime を生成する必要がある。用途によっては、実行したいスクリプトが大きくなるとオーバーヘッドを無視できない状況もあるかもしれない。うちの要件は小さいユーザー定義スクリプトを実行するだけなのでおそらくそれほど問題にはならないだろうという想定。

駐車場探し

3時に寝て8時に起きた。生活リズムが乱れてきた。

コードレビュー

年末にマージリクエストが届いていたのをレビューした。http リクエストが失敗したときのリトライ処理を google-api-go-client の sdk 側に委譲できないかを調べてみた。いくつか issue も上がっているが、おそらく次の issue の結論にあるように、互換性を考慮すると既存の仕組みを置き換えられないという話しのようにみえる。

sdk としては gensupport#RetryConfig のように、ヘルパー関数は用意されていて、例えば storage サービスでは Retry strategy として組み込まれている。しかし、これが sdk の http クライアントレベルで実装されているのではなく、それぞれのサービスごとに実装されているため、サービスによってリトライの仕組みがあったりなかったり、もっと言うとサービスごとに異なるリトライ実装になっていたりする。うちらは admin サービスを使いたいのだけど、そのリトライ処理は自前で実装するしかないというのをコードを読みつつ issue を読みつつ理解した。

駐車場の契約と保管場所使用承諾証明書の手配

社用車を購入する にあたって駐車場が必要になる。駐車場は本拠地 (会社のオフィス) から2km以内に借りないといけない。候補の駐車場の管理会社とやり取りして法人名義で駐車場を借りるのは問題ないとのこと。来週は私が出張で留守なので並行して納車の手続きを進めるため、この証明書を急ぎでほしいとお願いしたら今日・明日で作ってくれるということになった。朝から何度か電話して便宜を図ってくれた担当者に感謝。

オンライン飲み会の準備

毎年のことになっていて悪い運用なんだけど、交際費の予算を30万円と見積もっている。現時点で78,913円しか使っていない。交際費の予算消化も兼ねてこれからオンライン飲み会の機会を増やしていく。過去に働いていた職場の後輩と今度オンライン飲み会をすることにした。初めてのお酒を飲めない相手ということでソフトドリンクを手配した。アップルタイザー などがよいんじゃないかと思って混ぜてみた。これが新しいオフィスから ゆうパックスマホ割 で荷物を送付する初めての事例にもなった。オフィスから郵便局が徒歩2分ぐらいの立地なので郵便を出すのも便利。ほんとうによい立地のオフィスを借りられて満足している。

お仕事戻し

お仕事戻し

0時に寝て5時に起きた。昨日も疲れていたのか、不思議とよく眠れた。

年末のお仕事戻し

朝から近所のマクドナルドへ。今週は月・火とお休みしたため、いつも火曜日に書いている週報を書いていなかった。言うても3日分の作業なのでちゃっちゃと書いて送付した。私が休んだ日の定例会議はスキップされたようでその確認はなし。その後、issue のコメントをみたり、マージリクエストのコードレビューをしたりした。メンバーが課題管理システムを使うようになっているので、私が休んでいても後で見返してコメントを返せる。非同期/テキストコミュニケーションは働く時間帯があわないときに役に立つ。そういう雰囲気を学ぶ機会になればいいかもしれない。ある文字列の変換関数に go 1.18 で追加された fuzzing テストを実装してみようというリファクタリングの issue を追加していた。

私自身、まだ自分で実装したことはなかった。fuzzing テストを実装したマージリクエストがあったのでコードレビューした。実際に実行して動いているようにはみえるが、デバッグログを出力できなくてどういった振る舞いをしているのかを確認できなかった。簡単にできるんやと思っていたら意外と難しかった。また後で自分でも実装してデバッグしてみて振る舞いを再確認する。

小さい椅子

葬儀で斎場に2泊3日過ごしたときに畳の控え室に小さい椅子が4つほど置いてあった。正座が難しいお年寄り向けだと推測する。あの控え室でその小さい椅子を最も活用していたのは私だった。地べたに座るのと小さな椅子に腰掛けるので腰の負担がこんなに違うとは思わなかった。おそらく太ったことも影響している。ラップトップでキー入力するときに正座にしろ、あぐらにしろ、どちらも長時間続けることはできなかった。この小さい椅子なら2-3時間ぐらいは平気で作業できる。気持ち程度の高さでも十分に椅子の役割を果たせるところに感心した。家用に購入して、いま小さい椅子でこの日記を書いている。

休日のオンライン学習

0時に寝て夜中に吐き気がして2回ほど起きて3時と5時に起きて8時に起きた。なかなか苦しい寝方をした。

ヤフートラベルと一休.comのシステム統合

アーカイブ公開されたらみようと思いつつ忘れてたので見返した。

雑なめも。また機をみて見返すこともあるかも。

  • バックエンドは完全に一休側に寄せるという大きな意志決定を2016年に行った
    • この意志決定はフロントエンド統合にも大きな影響を与えた
    • ふじもんさんの意志決定がよかった?
  • 今日の話しはマルチブランドデザインシステム統合がメイン
    • 開発者が50-60人程度で半年ぐらいで launch できた
    • nuxt/vuejs で開発している
    • スタイルは tailwindcss を使っている
    • 実は launch した後にこのシステムが必要だとわかった
      • 開発者とデザイナー間の細かい意思疎通が困難
      • 外部からデザインシステムに詳しい人にも来てもらっていろんな議論をした
      • ガイドラインを言語化するところから始め、最終的にソースコードの共有ができるようになった
    • 終わってからデザインシステムそのものは重要ではないと気付いた
      • この過程で開発者とデザイナー間のどのように共通化するか、あるいはしないかと議論を繰り返し行ったことが重要だったと当事者がインタビューで語っていた
      • デザインシステムの開発を通じてデザインの共通認識をもてたことがよかった
  • 波及効果
    • 同じソースコードから少し異なる体験の開発のノウハウができた
    • ふるさと納税に特化した宿泊予約サイトを作った
  • 統合は終わりではない、lauch したところが始まり
    • 統合後にいろいろな施策をすることで課題がみえてくることがある
  • 全国旅行支援は1つの開発で2つの体験をつくることができた
  • Q. デザイナーと開発者はわりと仲が悪いのでは?価値観や考え方が異なるのですり合わせるのは難しいのでは?
    • 過去の一休でも起きていた
    • 一休のチームはデザイナーと PM と開発者で構成されている
      • このチームが一緒に働いていてチームでなるべく意志決定している
      • 普段から一緒に働いていると仲が悪いということはなかった
      • とはいえ、仕事のプロセスが異なるので課題はあった
        • 地道に丁寧にすり合わせを行った
        • 外部から講師を読んで中立的な立場でワークショップを何度も行った
    • デザイナーと開発者を別の組織にしているとコミュニケーションの壁ができてしまうかもしれない

go の学び直し

テストの学び直し に引き続き、Gopher塾 #2 - Goらしいコードの書き方 - DAY 1 に参加した。

テストの次のプログラミングの話しだったので内容そのものは難しくはなかったけど、改めて重要な項目を選抜しているのだと考えると学びはあったと思う。参考になったことをいくつか覚えている範囲でまとめる。名前の付け方について感覚的に理解していたし、実際に私はそうしているけど、コードレビューしていて自然になっていないコードを指摘する機会も多いので一定の習熟を要するのかもしれない。いま毎週勉強会をやっていて私が講師として話している。ネタがなくなってきたり大変になったきたら準備の少ないコードリーディング会もやってみたいと思った。

  • google Go Style
  • derrors.Wrap
  • 名前に文脈を与えるという概念
    • 相対的な名前をつける
  • 準備の少ないコードリーディング会
    • お題(読むパッケージ)を決める
    • 選んだお題に期待することを当日話す
    • 時間を決めてみんなでそれぞれ読む(20分とか)
    • 読みながらSlackのスレッドにメモをしていく
    • 残りの時間で気になったところを議論する
    • 自分が気づけなかった点を知ることができる

echo のよさの1つはテストがやりやすい

にわかサッカーファンになって、20時頃に1-2時間寝て24時からワールドカップのクロアチア戦をみて3時に寝て8時に起きた。睡眠のリズムが完全に狂ってしまった。

echo のテストのやりやすさ

うちのチームでは http フレームワークに echo を採用 している。その後、開発を継続していていくつか http ハンドラーも実装されてきた。そろそろ http ハンドラーのテストを書いていこうと参照実装を私が書いてみた。メンバーが知らないことは、マネージャーの私が参照実装して教えるといったやり方をしている。echo.HandlerFunc に echo.Context を渡すシンプルなインターフェースはテストを書くときに http ハンドラー以外の依存関係 (例えば db とのコネクションなど) を context を介することでモックと差し替えるのが容易になる。

tests := []struct {
	name    string
	ctx     echo.Context
	err     *echo.HTTPError
} {
    ...
	func() echo.Context {
		data := `{...}`
		c := newEchoContext(http.MethodPost, "/endpoint", data)
		c.Set("db", &myMockDB{})
		return c
	}(),
    ...
}

if err := myHTTPHandler(ctx); err != nil {
    ...
}

こんな感じで context にモックを入れてしまえば http ハンドラーそのものの単体テストを簡単に書ける。そんなことをツィートした。

そしたら podhmo からレスをもらったので go のリクエストコンテキストの扱いについても議論した。

  • リクエストスコープのものを context に入れるのは同意
  • それ以外のスコープのものを context に入れるのは懸念がある
    • http ハンドラーのレイヤーとアプリケーションのレイヤーが明確に分かれているならまだ理解できる
    • アプリケーションのレイヤーで context を自由に使うと依存関係や統制が取れなくなる
      • これは私も同意するところでアプリケーションのレイヤーにリクエストコンテキストを渡す必要はない

オフィス住所の更新

引き続き、住所変更の手続きを時間をみつけてやっている。同じ銀行の住所変更の手続きでも PayPay 銀行と三菱 UFJ 銀行ではまったく異なる。前者はオンラインでアカウント情報を変更するだけで済んだ。簡単。一方で後者はオンラインではできず、来店予約をとって対面で行う。当日に登記事項証明書の原本をもってこいと。なんという面倒臭さ。よくよく考えたら法人の登記事項証明書は誰でも取得できる。行政のシステムがどうなっているか知らないが、銀行が法人の住所変更を自分たちで調べることもやろうと思えばできるはず。登記事項証明書をオンラインで取得する手数料は500円になる。来店予約すると応対する人の人件費を考えたらシステムの手数料を支払った方が安いのではないか。

国税庁の管轄ではあるが、国税庁法人番号公表サイト から法人の住所変更そのものは確認できる。これは e-tax で次の2つの書類を申請した。登記事項証明書がなくても申請はできた。なにも言ってこなければ問題ないのかな?

  • 異動届
  • 給与支払事務所等の開設・移転・廃止の届出

有償にはなるが 登記情報提供サービス というのがあって登記情報をオンラインで確認できる。このサービスを会社で契約していればいつでも確認できるはず?