基本はサーバを Node.js にしてフロントエンドもバックエンドも JavaScript にしてます
たまには気分を変えてサーバが JavaScript でない構成で作ることがあったのですが やっぱり揃ってたほうが楽でした
フロントエンドとバックエンドだとやることが違ってそれぞれに適した言語がベストみたいな考え方もありますが 最近って昔はバックエンドでやってたこともフロントエンドでやってしまいます
あんまりやることが変わらないので 同じような処理を別言語で 2 回書く必要が出て ただ面倒なだけだったり
完全に同じ処理を両方で書く部分もあって そのまま移植できたらいいのですが 言語ごとの機能の違いで別の書き方にしないといけなくて面倒でした
ひとつはサーバに送信するデータのチェック
チェックのたびにサーバに送りたくはないので JavaScript でチェックしてから最終的なチェックのみをサーバでしてます
JavaScript でチェックしてるので普通ならサーバサイドでのエラーは起きないです
丁寧なチェックやメッセージ表示は ブラウザ内で行って サーバ側は最低限の受け付けてはいけないものを拒否する程度です
なので基本的にはブラウザとサーバで同じ処理にはなりませんでした
特に SPA で API 呼び出し前提なので フォームと API が 1 対 1 で対応しません
例えば ユーザ情報編集画面で名前の変更とテーマや背景色の変更は別ページでできるとします
API まで分ける必要はないので ユーザ情報を変更する API 一つだけにします
画面的には名前とテーマを同時に変更できないのに API を直接呼び出せばできてしまいますが できても問題ないので許可しています
逆に一緒に変更したいのでユーザ情報とまた別の情報を 1 つのフォームで変更できるようにするときは保存時に 2 つの API を呼び出します
API ベースでなくとも パスワードやメールアドレスの一致チェックみたいのはユーザの入力ミスを防ぐ親切機能みたいなものなのでブラウザ上だけで十分です
パスワードが◯文字以上とか 半角のみというのもサーバ側でまでチェックしなくても十分です
ということであまりチェック処理が負担になると考えてませんでした
ですが データによっては保存可能な条件が複雑で数十行程度のコードが必要になりました
必須な条件なのでサーバサイドでもチェックが必要です
完全に同じ処理を別言語で書いていて すごく無駄なことをしてる気分でした
二回書くことでロジックのミスに気づける可能性が増えるみたいなポジティブなことを言う人もいますし たまに見つけれたりはしますが どっちかにバグが入ると動かなくなるのでバグ発生確率が上がってるような気がします
Node.js だとモジュールにしておいてサーバからも同じファイルを読み込むだけで使えるのに
どの言語でも動くように事前にチェック処理用の関数を用意しておいてルールを JSON みたいな多くの言語で扱えるデータとして書けばいいかなと思ってなにか作ろうとしたことは何度かあります
便利な関数を作るとなるとすごく大変なので 四則演算や比較みたいな基本的な機能だけに対応してあとは組み合わせる感じと考えてました
「[">", 100]」 で 100 以上とか 「["if", condition, then, else]」 で分岐とか 「["regex", "/^a/"]」 で正規表現マッチングとか
構文的には Lisp みたいな感じ?
ただ実際に必要になる複雑なケースは JavaScript でもチェック処理が数十行になったりするもので こういうのの組み合わせで実現はかなり辛いです
書いたとしても長すぎますし 日付計算みたいな言語側に付いてる便利機能を使いたい部分も多いです
問題のほうが多いので実用まで行かずにやめました
同じ処理がある程度必要になる以上 揃えておいたほうが何かと便利で むしろ別言語を使うメリットのほうが出てきません
ふたつめも似てますが ブラウザ内を前提とした処理がサーバ側でも必要になるケースです
API 前提だと サーバ側はデータしか扱わず HTML みたいな見た目は気にしませんし ユーザ用の表示も知る必要がありません
数値が金額で 「,」 付きで表示が必要かとか この値はフラグで 0 なら 「無効」 と表示して 1 なら 「有効」 と表示するとか enum 値の日本語ラベルみたいなのも知らなくていいです
そういうユーザ用のデータはブラウザ側だけに置いておけばいいです
と思っていたのですが HTML 以外でユーザ用の表示を作らないといけなくなるとサーバサイドにこれらを持ってこないといけません
JSON などの静的なファイルとして保持しているならサーバ側の言語が違っても対応しやすいでしょうが 動的な部分もあって JavaScript のモジュールとして管理しているとサーバサイドでは JavaScript を実行できずに困ります
最近だとエクセルや PDF の出力でもブラウザ側でできてしまうので あまりサーバ側でしないといけない処理はありませんが セキュリティ的な意味で署名や暗号化とかが入ってくるとサーバ側でやらざるを得ませんし メールや Push 通知などの方法でユーザ用の通知を送信する場合もサーバ側でせざるを得ないところです
結局ブラウザ側だけのつもりだった処理をサーバ側でも実装することになり 同じものを二重に管理してるという面倒な状態になります
同じ仕様を基にフロントエンドとバックエンドで完全に分かれて作って最後に結合するみたいなことをやってる大きなプロジェクトだとあまり気にならないのかもしれませんが 全部一人で作ってるとすごく気持ち悪い部分なんですよね
最近は WebAssembly の対応が進んでますし サーバサイドを Node.js 以外で作るなら フロントエンドもその言語で作って WebAssembly 出力するのもありなのかもしれません
ただ現状だと負荷が高いアルゴリズムなどの関数やゲームなどのグラフィック処理がほとんどで 一般的なウェブフロントエンドの処理全体を WebAssembly でできるのって限られてる気がしますけど
Rust や C# はフロントエンド用フレームワークみたいな感じで作れるのを見た気がするけどどうなんでしょう
Elm みたいに JavaScript でしかできない部分を別に作ってポートして呼び出すみたいなのがいっぱいだとイマイチな気がしますけど
とりあえず今のところはサーバサイドも JavaScript がベストだと思います