VercelでNode.js以外のランタイムを動かしてみる（Go, Python, Ruby）

Vercel といえば Next.js なので、 Node.js を動かすものというイメージがあります。

ですが、Vercel では Node.js 以外のアプリケーションもデプロイすることができます。

想像以上に簡単にデプロイできて、すごかったです :hushed:


## 公式が対応しているランタイム

Vercel は以下のランタイムに対応しています。

- Node.js
- Edge
- Go
- Python
- Ruby


## コミュニティ・ランタイム

公式がサポートしているランタイムとは別に、ユーザが作成したコミュニティ・ランタイムも存在します。コミュニティ・ランタイムには、以下のランタイムがあります。

- Bash
- Deno
- PHP
- Rust
- Bun

コミュニティ・ランタイムは、GitHub の [Vercel Community](https://github.com/vercel-community) リポジトリで管理されているようです。


## ランタイムの比較

基本的に、サーバレスなアプリケーションを構築をする場合には Node.js、Edge で動かしたい場合には Edge (JavaScript) を使うことが想定されているようです。

Go, Python, Ruby については、 `2023/12/2` 現在でベータ版となっています。

## うごかしてみる

公式にサポートされている 5 つのランタイムを実際に動かしてみましょう。

適当に GitHub リポジトリを作成して、次のようなファイル構成にしてみました。

```
.
├── Gemfile
└── api
    ├── edge
    │   └── hello.ts
    ├── go
    │   └── hello.go
    ├── javascript
    │   └── hello.js
    ├── python
    │   └── hello.py
    └── ruby
        └── hello.rb
```

5つのファイルそれぞれの中身は、ほとんど公式ドキュメント通りですが、次の通りです。

```ts:/api/edge/hello.ts
export const runtime = 'edge';
 
export function GET(request: Request) {
  return new Response(`I am an Edge Function!`, { status: 200 });
}
```

```go:/api/go/hello.go
package handler
 
import (
  "fmt"
  "net/http"
)
 
func Handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "<h1>Hello from Go!</h1>")
}
```

```js:/api/javascript/hello.js
export default function handler(request, response) {
  const { name = 'World' } = request.query;
  return response.send(`Hello ${name}!`);
}
```

```python:/api/python/hello.py
from http.server import BaseHTTPRequestHandler
 
class handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        self.wfile.write('Hello, world!'.encode('utf-8'))
        return
```

```ruby:/api/ruby/hello.rb
require 'cowsay'
 
Handler = Proc.new do |request, response|
  name = request.query['name'] || 'World'
 
  response.status = 200
  response['Content-Type'] = 'text/text; charset=utf-8'
  response.body = Cowsay.say("Hello #{name}", 'cow')
end
```

```:Gemfile
source "https://rubygems.org"
 
gem "cowsay", "~> 0.3.0"
```

あとはこれを GitHub にプッシュして、Vercel にインポートするだけでデプロイできます。

## アクセスしてみる

デプロイしたAPIに実際にアクセスしてみます。

### Edge

https://vercel-runtime-example.vercel.app/api/edge/hello

![/api/edge/helloの画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/f349bd95-ac50-4c52-27b1-e66417e3098a.png)

### Go

https://vercel-runtime-example.vercel.app/api/go/hello

![/api/go/helloの画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/c1f52f73-348f-72e4-5dc1-bb341b3d839d.png)


### Javascript

https://vercel-runtime-example.vercel.app/api/javascript/hello

![/api/javascript/helloの画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/f0e90964-c6ce-4085-86d2-5bb004169c98.png)


### Python

https://vercel-runtime-example.vercel.app/api/python/hello

![/api/python/helloの画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/6e087d50-7d85-8328-870c-c9c827da0934.png)

### Ruby

https://vercel-runtime-example.vercel.app/api/ruby/hello

![スクリーンショット 2023-12-02 0.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227791/1712ef62-d0b6-0a95-352c-7bd3bc94c8fa.png)


## Node.js 以外のランタイムはどんなときに使える？

Go, Python, Ruby はまだベータ版なので、商用で使うのはまだ早いかもしれません。

それでも、検証目的のAPIや画像変換APIに活用すると、スピーディに開発を行えそうです。

あと、デプロイまでの流れが超シンプルなので、プログラミング初学者の入門としても優秀だと思います。


## Flask と Django が使える

これもいいなと思ったのですが、Python のランタイムには Flask と Django が含まれているようです。
素晴らしいです:clap:


## まとめ

Vercel といえば Node.js のイメージしかなかったですが、Go、Python、Ruby のAPIをとても簡単にデプロイできることが分かりました。

ファイル１つ作ってGitHubにプッシュするだけでAPIが叩けるようになるって、最高ですね！

APIを作ることの簡単さでいうと、他のホスティングサービスと比べてもかなり優れていると感じました :+1:


## 参考

- [Configuring the Runtime for Vercel Functions](https://vercel.com/docs/functions/configuring-functions/runtime)