iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🌐

Simple HTTP Server in V

に公開

V Language

Refer to the following for setting up the V language environment, etc.
https://zenn.dev/platina/articles/5ce280b557c4ca

Implementation

Creating a Project

First, create a project.

Terminal
v new http_server

Writing Code

We will use the official library called vweb.
https://github.com/vlang/v/tree/master/vlib/vweb

You can probably understand most of it by looking at the code.

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!')
}

When you run this:

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

In this way, the server starts on port 8080.

Let's Try Accessing It

When you access http://localhost:8080,

it will be displayed like this.
This is due to the following part of the code:

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

Basically, an endpoint with the same name as the function is created.
Since the function name is index, accessing / returns '<h1>Index</h1>' as html.

When you access http://localhost:8080/hello,

"Hello, World!" is displayed like this.

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

The function name is world, but since ['/hello'] is specified, the /hello endpoint is created.

When you access http://localhost:8080/hello/hoge,

"Hello, hoge!" is displayed like this.

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

By specifying it like ['/hello/:user'], you can obtain the parameter as-is by receiving user as a function argument.

For http://localhost:8080/post, by sending a POST request,

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

it returns this.

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

The [post] specified here seems to be the post of the Method enum in net.http.
It feels a bit strange since it's not imported from anywhere, but it might be better to just accept that this is how the V language is.

Details of Method
https://github.com/vlang/v/blob/master/vlib/net/http/method.v

To specify a POST endpoint,

// 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!')
}

by doing it like this, if you send a POST request to http://localhost:8080/post/foo,

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

it will return.

Conclusion

We have created a simple HTTP server in the V language.
vweb also seems to be able to serve static files. For details, please refer to the vweb source code.
https://github.com/vlang/v/blob/master/vlib/vweb/vweb.v

GitHubで編集を提案

Discussion