会社のサイトはNext.jsで作ったものをexportして完全に静的なサイトとして作成していた。が、色々あってバックエンドが欲しくなった。AWSのAmplifyにデプロイしていたので、あとからサーバー追加するのめんどいなあというのと、管理画面とか作りたくないし簡易的なものでいいからとGASにしたのだが、ハマりどころがあった。(あとAmplifyでも今は普通にNext.jsのバックエンドが使えるので使えるようにした)
特にハマったのはdoPost。doPostはエンドポイントにPOSTでリクエストが送られてて、GAS側のコードがリクエストボディを使用していた場合にはlocationヘッダが帰ってきてリダイレクトされる。実際の処理はリダイレクト先で行われてそこからレスポンスが帰ってくる仕組みのようなので、そこで色々と問題がおこる。特に、Googleの認可を挟もうとするとややこしくなる。
最初はdoPostの処理をNext.jsのAPIルートを経由して呼ぼうかと思っていたのだが、Nodeからだと何故か401になる。クライアント(ブラウザ)から直接GASのエンドポイントを叩くと200で返ってくる。なんでだと思っていたが、このエンドポイントはGoogleの認可を使用する設定にしていので当たり前といえば当たり前のことだった。
で、色々やっているとGASではステータスコード200しか返せなさそうだということがわかった。エラーの場合はerrorなどのキーを持つオブジェクトを返して、ブラウザ側でエラーハンドリングしようかと思っていたのだが、クライアントから直接呼ぶとリダイレクト先からのレスポンスが受け取れない。レスポンスボディが空になってしまう。色々試してみたがどうもダメそうだった。
これは多分一回リダイレクトを挟んでしまうことが関係しているように思う。詳しい原因はわからない。
なので、最終的にはGoogleの認可を外して、リクエスト時にパスワードなりトークンなりを付与してサーバー側でそれを検証するコードを書いた。そしてNext.jsのAPIを経由するようにした。すると期待通りにレスポンスボディを取得できた。
なぜブラウザから直接呼ぶとリダイレクト先のレスポンスボディが取れなくて、Node.jsから呼ぶと取れるのかは謎。調べればわかるのかもだけど、人生は有限なのでもっと切実な問題に時間を使いたい。
GASは本当にログを取りたいくらいの用途でだけしか使うべきではないと思った。。サーバーサイドが簡単にセットアップできる何かがほしい。人類がずっと求めているのになかなか提供されないもの、それが簡単なサーバーサイドだ。人はみんな簡単にセットアップできるサーバーサイドを求めるし、実際にそれを実装可能だと考えるのだが、作ってみると必ず複雑になる。必然的に複雑さを要求するのがサーバーサイドなのかもしれない。なぜなら、そもそも複雑なことをしたいからこそサーバーサイドが欲しくなるからだ。とてもつらい。