一言でいうと、秒で開発用のHttpサーバを立てます。
(2021.1.25更新: GrapevineのバージョンがVer4からVer5に変わりました
この記事はVer4ベースで記載されています。Ver4は現在Grapevine-legacyという名前になっています。Ver5についても考え方は同じですが、使用方法が一部違っておりますのでご留意ください。)
課題が多いC#のHTTPサーバ
アプリのテスト用にC#でHttpリクエスト(REST)に答えるサーバをお試しに立ち上げたいとして、思ったよりも難しいことに気づきます。
- ローカルテスト用、実機?環境の対抗機としてPCと外部機器で1対1で単体/結合テスト用のMocサーバを立ち上げたい
- できればexeスタンドアローンでサーバを立ち上げたい(apache/IIS立ち上げができない環境)
- VisualStudioではASP.NET MVCを使用することになるが、基本的にIIS依存。IISに依存しない方法については多分調べる時間の方が長い。(気づいたらASP.NET MVCの歴史を勉強されられてた。勘弁してほしい)
- HttpListenerでHTTPのレスポンスを書くのが一般的だが、URLの処理(ルーティング)は自分で全部実装しないといけない。例えば、"http://localhost/page/" というURLや引数に対する文字列処理をしないといけない。
- URLの自前処理は非常にセキュリティやバグのリスクが高く、普通はやらない。
と言ったところを堂々巡りします。
そこで、Grapevineというライブラリを見つけたので紹介したいと思います。.NET的にNuGetで入れてチョイチョイで立ち上がるので安心。
Grapevine
git: https://github.com/sukona/Grapevine
Getting started: https://sukona.github.io/Grapevine/en/
LINQPad上で早速立ち上げてみる
LINQPadでF4→Add NuGetから"Grapevine"を検索して"The embeddable~"という長ったらしいのがGrapevineライブラリ本体です。もしLINQPadのNuGet機能が使用できない場合、GrapevineのサイトからDllを入手してF4→Browse...より参照してください。
次にF4→Additinal Namespace Importsタブから名前空間を登録します。C# のUsingにあたるところになります。
とりあえず以下の名前空間を登録します。
Grapevine.Server
Grapevine.Server.Attributes
Grapevine.Interfaces.Server
Grapevine.Shared
あとはGetting started: https://sukona.github.io/Grapevine/en/ に沿って進めます。
一番最初のサンプルコードをLINQPadに貼り付けます。
using (var server = new RestServer())
{
server.Start();
Console.ReadLine();
server.Stop();
}
LINQPadのLanguageがStatementsまたはC# Programになっていることを確認して、再生ボタンを押してください。
すると以下の画像のようになり、ReadLine()で入力待ちの状態になります。
この状態になれば"http://localhost:1234" のURLに接続できるようになります。
ポートやホスト名を変える場合はRestServerのコンストラクタで指定できます。
終了時は、LINQPad上ではコンソール入力用の黒い帯が出ているので、ここに何か入れると次の行に進んで正常終了できます。
(追記)
ReadLine()で待ち受けるとLINQPadのダンプがスレッド実行待ちになって止まるので、以下のような動かしっぱなしのコードの方が良いようです。止めるときはメニューのQuery→Cancel All threads and Resetsで止めます。
var server = new RestServer();
server.Start();
NuGetやサイトからDll取ってくる→ソースコピペ→実行の3ステップで立ち上げまで一瞬でした。
引き続きGetting startedを進めるのですが、クラスを書く場合はLINQPadのLanguageをC# Programに変更してください。
次に書いてあるLoggingについては、標準出力へのトレースログはそのままLINQPadへ出力されます。
Grapevineでのサイト(システム)構築
GrapevineではURLのルーティングはクラスやメソッドに属性をつけるだけで自動的にやってくれるので、完全にストレスフリーです。
Routingでヒットしたメソッドはdllの定義順に実行され、context.SendResponse()などで、レスポンスを返した時点で以降のRoutingは実行されません。また一度もレスポンスを返す処理が実行されなかった場合、ライブラリのエラーレスポンスとなります。(私の環境では文字化けした怪しめの出力になりました)
(実際に簡単なサイトを構築した例は別途掲載予定。)
さいごに
GrapevineはIISとSystem.Webを駆逐してやると謳っているだけあって、使用感がシンプルで好感が持てます。
LINQPadを使用して、秒でスクラッチコードを書いて動かせるので素晴らしい。