🦔

Golang net/httpでRESTful APIを作る #1 ルーティングを書く

2021/10/27に公開

はじめに

業務では、PHPやTypeScript(Node)でサーバサイドを書くことが多いですが、副業で参画しているプロジェクトで、Golangを使ってRESTfulのWEB APIを書くことになりました。(提案したらOKしてくれた)

その際の、エントリポイントからルーティングまでの構成を紹介したいと思います。より良い構成などがあればぜひコメントでご指摘くださいm(_ _)m

この記事でわかること

  • net/httpでルーティングとコントローラー(Laravelでいうところの)を分ける方法
  • RESTfulにするために、メソッドごとに機能を分ける方法

ソースコード

以降ファイル単位で実際のコードと説明を記述していきます。

app.go

app.go
package main

import (
    "log"
    "net/http"
)

func main()  {
    setRouter()

    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal(err)
    }
}

setRouter()は、関数化して別ファイルでルーティングを設定しています。

router.go

route
package main

import (
    "net/http"
    "os"
)

// setRouter ルーティングをセット
func setRouter() {
    // ユーザのルーティング
    http.HandleFunc("/api/user", userCtrl)
}

http.HnadleFuncで、パスとマッチしたときに実行する関数を指定します。
userCtrlは、実行したい関数の名前です。userCtrl()も別ファイルで定義しています。
イメージは、laravelのweb.phpです。
ここで、注意したいのが、この段階ではメソッドを分けないという点です。userCtrl()の中でメソッドを振り分けていきます。

ctrl-user.php

ctrl-user
package main

import (
    // 次回の記事で紹介します "local.packages/service"
    "net/http"
)

func userCtrl(w http.ResponseWriter, r *http.Request)  {
    // 次回の記事で紹介します thisService := service.UserService.Constructor(w)
    if r.Method == http.MethodGet {
        // ここで本来はサービス層に、取得したクエリの値などを渡す
	// ここも次回の記事で紹介します。
	// user := thisService.getUser(userId)
	w.Write("成功") // 本来はJson形式などで、userを返す
	return
    } else if r.Method == http.MethodPost {
    } else if r.Method == http.MethodPut {
    } else if r.Method == http.MethodDelete {
    }
}

userCtrl()の2つの引数は、前述のファイルのhandleFuncから暗黙的に渡されています。
メソッドの振り分けは、条件式で行います。それぞれの実行したいメソッドで必要なコードを書いていきます。
このファイル内では、リクエストからの値取得などを行い、サービス層に対して値を渡していくところまでを責務と想定しています。
サービス層、リポジトリ層については、次回以降の記事で紹介します。

まとめ

以上、golange標準パッケージのnet/httpでルーティングを書いてみました。
次回の記事で、サービス層やリポジトリ層の構成と、オブジェクト指向っぽく書いていく方法を紹介していきますので、お楽しみに!

最後まで読んでいただき、ありがとうございましたm(_ _)m

Discussion