はじめに
「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」3日目の記事は、Goの標準ライブラリで作る簡単なAPI制作ハンズオンです。
この記事では、Go言語の標準ライブラリである net/http を活用し、フレームワークに頼らずにサーバーを立ち上げます。
- APIがそもそも何かわからない方
- Go言語で初めてAPIを作成しようとしている方
- 普段フロントエンド開発に携わっており、APIがどのように動いているのかを知りたい方
Go言語でのバックエンド開発の基礎を固めて、次のステップへと進むための足がかりにしましょう!
APIとは
APIの定義について、MDNに以下のような説明がありました。
Application Programming Interfaces (APIs) は、開発者が複雑な機能をより簡単に作成できるよう、プログラミング言語から提供される構造です。
例えば、フロントエンド(HTMLやJS)のコードでは、ユーザーインターフェース(UI)を提供し、ユーザーからの操作を受け付けます。
その裏側では、ユーザーのデータ保存、情報の取得、複雑な計算処理など、多くの「見えない」処理が行われています。
これらの「見えない」処理を担っているのがバックエンドであり、フロントエンドとバックエンドが連携するための窓口となるのがAPIです。
「見えない」処理の中身について、大まかな処理フローは以下になります。
- (前提)サーバー起動
- ルーティングの設定によるHTTPリクエスト受け取り
- ハンドラーの設定によるHTTPリクエスト処理
- ハンドラーの設定によるHTTPレスポンス
今回は、この処理フローをGoで実装していきます。
【実践】Goの標準ライブラリでAPIを作る
Goの開発環境が揃っていること、そしてGo Moduleの初期化(go mod init)が終わっていることを前提とします。
方法がわからなければ、以下の記事を参考にやってみてください!
STEP 1:サーバー起動
最初にサーバーを起動するプログラムを書いていきます。
package main
import (
"fmt"
"net/http"
)
func main() {
fmt.Println("ポート番号8080でサーバーを起動します")
http.ListenAndServe(":8080", nil)
}
なんとこれだけです!簡単ですね^ ^
もちろんエラーハンドリングなどを、さらにできればいいのかもしれませんが、今は超最小構成にとどめておきます。
ここで、要チェックポイントの説明です。
-
net/http: Goの標準ライブラリで、HTTP関連の機能を提供します -
ListenAndServe(): HTTPリクエストを処理するためのサーバー起動関数で、第1引数にポート番号を指定するのがポイントです
go runを行うと、ポート番号8080でサーバーが起動します。
まだこの段階では、ターミナルにポート番号8080でサーバーを起動しますしか表示されません。
Ctrl + Cでサーバーを切って、次のステップへ進みましょう!
STEP 2:ルーティングの設定によるHTTPリクエスト受け取り
先ほどのコードを少し変えます。
package main
import (
"fmt"
"net/http"
)
func pongHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf("pong")
}
func main() {
// ルーティング設定
http.HandleFunc("/ping", fmt.Println("pong"))
fmt.Println("ポート番号8080でサーバーを起動します")
http.ListenAndServe(":8080", nil)
}
-
ハンドラーの定義: ここでは
pongHandlerとして定義しており、2つの引数を受け取ります-
http.ResponseWriter: クライアントへのレスポンスを書き込むためのインターフェースで、これを使ってHTTPステータスコードの設定や、レスポンスボディの書き込みを行います -
*http.Request: クライアントからのリクエストに関する情報(URL、HTTPメソッド、ヘッダー、ボディなど)が含まれています
-
では、go runして、ブラウザなどでhttp://localhost:8080/pingにアクセスしてみてください。
ターミナル側で、pongという出力があれば成功です!
でも、ターミナルにただ表示されるだけでは面白くないので、次のステップでJSONを返すように変更します。
STEP 3:ハンドラーの設定によるHTTPリクエスト処理
もうお分かりかと思いますが、先ほどのpongHandlerの中身を変更すると、いろいろな処理を書くことができます。
データベースに接続して、データの保存やアップデートなど、いわゆる「CRUD」処理を記述するのが、代表例です。
Handlerの処理が大きくなってきた場合、コードを分割していきますが、それはアーキテクチャとか設計の話につながってくるので、ここでは割愛します。
STEP 4:ハンドラーの設定によるHTTPレスポンス
最後に、JSONを返していきましょう。
先ほどのコードを、以下のように変えます。
package main
import (
"encoding/json"
"fmt"
"net/http"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func pongHandler(w http.ResponseWriter, r *http.Request) {
u := User{Name: "Mamenz", Age: 20}
response, err := json.Marshal(u)
if err != nil {
http.Error(w, "JSONエンコードに失敗しました", http.StatusInternalServerError)
return
}
w.Write(response)
}
func main() {
http.HandleFunc("/ping", pongHandler)
fmt.Println("ポート番号8080でサーバーを起動します")
http.ListenAndServe(":8080", nil)
}
まず、Userという構造体が定義されています。
これが、今回レスポンスするデータの型定義です。
この構造体のタグについての意味は、以下の記事で解説していますので、わからない方は以下の記事を見てください。
ハンドラー内では、実際に表示させたいデータの定義を行っています。
JSON変換の際にエンコードのエラーハンドリングも行った後、ResponseWriterを使って、HTTPレスポンスを定義しています。
ではもう一度、go runして、ブラウザなどでhttp://localhost:8080/pingにアクセスしてみてください。
今度は、ブラウザなどにuで定義したデータが反映されたのが確認できたと思います!
おわりに
今回の記事では、Goの標準ライブラリを使って、サクッと簡単なAPIを書いてみました。
私自身は普段、サードパーティ製のライブラリを使うことが多いのですが、改めてGoの標準ライブラリを使って書いてみたことで、内部の仕組みに少しだけ注目できて、とても学びになりました!
最後までお読みいただき、ありがとうございました!
この「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」では、GoやJavaを使い、APIの作り方、データベースとの接続、テストやDockerといった気になったバックエンド技術の基本を振り返った学びを共有しています。
ぜひ他の記事もチェックして、筆者がこのひとりアドカレを完遂することができるか、確認してみてください(^^)
学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025
それでは、明日の「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」の記事もお楽しみに!
参考文献