この記事は 夏のブログリレー 18日目の記事です。
はじめに
最近は、フロントエンドとバックエンドの両方を TypeScript で開発する「Full-Stack TypeScript」を採用するプロダクトが増えているらしいです。
ところで、C# でも同様のことができます。
というわけで、この記事では「Full-Stack C#」で Web 開発をする魅力をお伝えしていきます。
使う言語を統一するメリット
本記事で取り上げている C# 以外にも、TypeScript や Rust などの言語でバックエンドとフロントエンドの両方を書けるような環境が整いつつあります。
では、言語を統一するとどのような嬉しさがあるのでしょう?
型定義を共有できる
OpenAPI スキーマから言語ごとに型定義とメソッドの定義を生やして……という面倒な作業が不要になりますし、OpenAPI スキーマで定義するよりもさらに柔軟な型定義ができます。
さらに工夫次第では API 定義をインターフェースに落とし込むことができ、ソースコードそのものを仕様書にすることができます。
学習コストを削減できる
同じ言語、同じフレームワーク、同じライブラリ群を利用できるようになるため、学習コストを削減することができます。1つの言語を学べばバックエンドもフロントエンドもある程度書けるようになって、かなりお得です。
C# で開発するメリット
では、TypeScript や Rust ではなく C# を採用するメリットは何でしょうか?
IDE による強力な開発支援を得られる
C# の魅力はなんといっても IDE の充実度です。C# で開発する上で必要な作業はだいたい IDE 上で完結します。
またデバッグ機能はかなり強力で、ブレークポイントを設定できるのはもちろん、実行中に好きな式を入力してその実行結果を見ることができますし、Docker 上で動くプログラムのデバッグもできたりします。
高パフォーマンス
近年は .NET 公式が提供する各ライブラリでパフォーマンス改善が進み、現在ではサードパーティ製のライブラリ等でも高パフォーマンスな API が利用されるようになっています。
また、.NET Runtime 自体のパフォーマンス改善も急速に進んでおり、特に JIT コンパイラが大きく進化しています。詳しい話をすると長くなるのでしませんが、JIT コンパイラが年々賢くなっており、実行時に最適化がかかりやすくなってきています。
充実したライブラリ
.NET は公式ライブラリがかなり充実しており、自作する前に調べてみると公式ライブラリが見つかるということもしばしばあります。
どうやって開発するの?
C# で Web サービスを開発する際は、基本的に ASP.NET Core というフレームワークを利用することになります。
この ASP.NET Core の中にも様々な機能があるのですが、その中でも基本的なものを紹介します。
ASP.NET Core MVC
MVC とは、Web アプリケーションを Model - View - Controller に分けて実装するパターンのことで、それぞれが責任を分担することで開発タスクの分担が容易になります。
このモデルは Web アプリケーション以外でも用いられますが、Web アプリケーションにおいては基本的に Model と Controller がバックエンド、View がフロントエンドということになります。
ASP.NET Core MVC では Model と Controller だけを提供することもできるので、HTTP API のみの実装に用いることもできます。ただし、後述しますが、この用途では Minimal API の仕様が推奨されています。
Minimal API
Minimal API とは HTTP API 実装のための新しいフレームワークです。
HTTP API を実装するには、先ほど紹介した ASP.NET Core MVC ではなくこちらを用いることが推奨されています。
Minimal API を用いると、他の言語で用いられているフレームワーク (Go の Echo など) と同じような感覚で HTTP API を構築することができます。
Blazor
Blazor は近年登場したフレームワークで、バックエンドとフロントエンドの両方を C# で作成できます。
フロントエンドはコンポーネントベースになっていて、Vue とかその辺の言語と同じような使用感で開発できます。
このフレームワークのおもしろい部分は、バックエンドとフロントエンドを†いい感じ†に繋いでくれるところで、デフォルトの構成では通信部分を記述する必要が一切ありません。何も設定しなくてもいい感じに繋いでくれるので開発がだいぶ楽になります。
フロントエンドを WebAssembly で提供することもできるので、高パフォーマンスな Web アプリケーションを構築することができます。
ただパフォーマンス面でやや苦しいところがあり、リソースが制限された環境下で動かすのはだいぶ難しいです。WebAssembly にするとサーバー側の負荷がほぼ無くなるのでいいんですが、WebAssembly で作るのには多少コツがいるのでお勧めできるかと言われると微妙です。
gRPC
gRPC は異なる言語間での通信を可能にする RPC フレームワークです。
もちろん C# (.NET) 向けにも用意されているので、ASP.NET Core アプリケーションに組み込むことができます。
ちなみに、gRPC は C# (.NET) 上でかなり高速に動作し、ベンチマーク では Rust と同等の性能を叩き出しています。すげ~
開発例
僕がこれまでに作成した WEB サービスのうち、バックエンドとフロントエンドの両方を C# で開発したものを紹介します。
それぞれフロントエンドで採用している技術が異なっているので、ぜひ3つとも読んでみてください。
dakoQ ─ 打刻管理ツール

学内施設やサークルの進捗部屋、部室、各イベントの入退場を記録するWEBサービスです。
諸般の事情から開発は中止になりましたが、このサービスでは SingnalR を用いた双方向通信によって、サーバー側で動的にレンダリングした DOM をクライアントに反映させる手法を利用していました。
この手法を用いると外部に公開する API を用意する必要がないため開発が楽になりますが、一般的な Web サーバーより多めのリソースを消費することになり、潤沢なリソースが無い環境には向いていません。
これが Blazor Web App のデフォルトの動作モードになっています。
Q-Palettes ─ traQスタンプパレット管理ツール

traQ のスタンプパレット (ユーザーが好みのスタンプをまとめたもの) を他人に共有できるサービスです。
このサービスではフロントエンドに WebAssembly を用いています。.NET の実行環境が載ったアセンブリを提供しているのでアセンブリのファイルサイズがやや大きく、初回読み込みが若干遅いですが、サーバー側は DOM のレンダリングをする必要がないので負荷が少なめです。
進捗部屋情報

当日以外の進捗部屋 (サークルで確保している講義室) を確認したいという需要から生まれたサービスです。今後の進捗部屋をリスト形式で確認することができます。
このサービスではフロントエンドをサーバー側で静的レンダリング (リクエストごとに1回だけ生成) しています。先ほど紹介した「dakoQ」は動的レンダリングでしたが、本サービスは静的レンダリングなのでサーバー側で処理をしてもそこまで負荷になりません。
おわりに
いかがでしたか?
C# を用いた WEB サービス開発に興味を持っていただけたら幸いです。
明日の投稿者は @Naru820 です。楽しみ~