🌐

V 言語で簡易HTTPサーバー

2022/04/05に公開

V 言語

V 言語の環境構築などは以下を参照
https://zenn.dev/platina/articles/5ce280b557c4ca

実装

プロジェクト作成

まずはプロジェクト作成。

Terminal
v new http_server

コードを書く

vweb という公式ライブラリを使います。
https://github.com/vlang/v/tree/master/vlib/vweb

おそらくコードを見れば大体わかると思います。

http_server.v
module main

import vweb

fn main() {
	vweb.run(&App{}, 8080)
}

struct App {
	vweb.Context
}

// http://localhost:8080
fn (mut app App) index() vweb.Result {
	return app.html('<h1>Index</h1>')
}

// http://localhost:8080/hello
['/hello']
fn (mut app App) world() vweb.Result {
	return app.text('Hello, World!')
}

// http://localhost:8080/hello/world
['/hello/:user']
fn (mut app App) hello_user(user string) vweb.Result {
	return app.text('Hello, $user!')
}

// POST http://localhost:8080/post_request
[post]
fn (mut app App) post_request() vweb.Result {
	return app.text('POST request!')
}

// POST http://localhost:8080/post/name
['/post/:name'; post]
fn (mut app App) post_with_name(name string) vweb.Result {
	return app.text('POST, $name!')
}

これを実行すると、

Terminal
$ v run .
[Vweb] Running app on http://localhost:8080/

このようにポート 8080 でサーバーが立ち上がります。

アクセスしてみる

http://localhost:8080 にアクセスすると、

のように表示されます。
上記のコードの

// http://localhost:8080
fn (mut app App) index() vweb.Result {
	return app.html('<h1>Index</h1>')
}

の部分によるものです。
基本的に、関数名と同じエンドポイントが作成されます。
index という名前の関数なので、/ にアクセスすると、'<h1>Index</h1>'html として返ってきます。

http://localhost:8080/hello にアクセスすると、

このように、 Hello, World! が表示されます。

// http://localhost:8080/hello
['/hello']
fn (mut app App) world() vweb.Result {
	return app.text('Hello, World!')
}

関数名は world ですが、 ['/hello'] という指定があるので、 /hello エンドポイントが作成されます。

http://localhost:8080/hello/hoge にアクセスすると、

のように、 Hello, hoge! が表示されます。

// http://localhost:8080/hello/world
['/hello/:user']
fn (mut app App) hello_user(user string) vweb.Result {
	return app.text('Hello, $user!')
}

['/hello/:user'] のように指定すると、関数の引数として user を受け取ることでそのままパラメータを取得できます。

http://localhost:8080/post には、 POST リクエストを送ることで

$ curl -X POST http://localhost:8080/post
POST request!

と返ってきます。

// POST http://localhost:8080/post_request
[post]
fn (mut app App) post_request() vweb.Result {
	return app.text('POST request!')
}

ここで指定される [post] は、net.httpMethod enum の post のようです。
どこからもインポートされてなくてなんか気持ち悪いですが V 言語はこういう感じだと割り切るといいのかもしれません。

Method の詳細
https://github.com/vlang/v/blob/master/vlib/net/http/method.v

POST エンドポイントを指定する場合は、

// POST http://localhost:8080/post/name
['/post/:name'; post]
fn (mut app App) post_with_name(name string) vweb.Result {
	return app.text('POST, $name!')
}

のようにすることで、
http://localhost:8080/post/fooPOST リクエストを送ると

$ curl -X POST http://localhost:8080/post/foo
POST, foo!

と返ってきます。

終わり

V 言語による簡易的な HTTP サーバーを作成しました。
vweb では他にも静的なファイルの配信もできるようです。詳細は vweb のソースコードを参照してください。
https://github.com/vlang/v/blob/master/vlib/vweb/vweb.v

GitHubで編集を提案

Discussion