本記事では、Go言語(Golang)、PostgreSQL、およびsqlxライブラリを使用して、親データと子データを取得し、それらをJSON形式で返すREST APIの構築方法を解説します。
ここでは、実際に使えるコード例を複数紹介し、データベースの操作方法を段階的に説明します。
コード例
商品データの取得
まず、商品情報を取得する基本的なAPIエンドポイントを作成します。
package main
import (
"database/sql"
"encoding/json"
"log"
"net/http"
_ "github.com/lib/pq"
"github.com/jmoiron/sqlx"
)
type Product struct {
ID int `db:"id" json:"id"`
Name string `db:"name" json:"name"`
Price int `db:"price" json:"price"`
}
func main() {
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
if err != nil {
log.Fatalln(err)
}
http.HandleFunc("/products", func(w http.ResponseWriter, r *http.Request) {
var products []Product
if err := db.Select(&products, "SELECT * FROM products"); err != nil {
log.Fatalln(err)
}
json.NewEncoder(w).Encode(products)
})
http.ListenAndServe(":8080", nil)
}
注文と商品詳細の統合
次に、注文情報とそれに関連する商品詳細を結合するクエリの例です。
// ...(前述のコードと同様のimport文)
type Order struct {
ID int `db:"id" json:"id"`
CustomerID int `db:"customer_id" json:"customer_id"`
Products []Product `db:"products" json:"products"`
}
func main() {
// ...(前述のDB接続コード)
http.HandleFunc("/orders", func(w http.ResponseWriter, r *http.Request) {
var orders []Order
query := `
SELECT orders.id, orders.customer_id, json_agg(products.*) as products
FROM orders
JOIN order_details ON orders.id = order_details.order_id
JOIN products ON products.id = order_details.product_id
GROUP BY orders.id`
if err := db.Select(&orders, query); err != nil {
log.Fatalln(err)
}
json.NewEncoder(w).Encode(orders)
})
http.ListenAndServe(":8080", nil)
}
複数テーブルの統合データ取得
最後に、顧客、注文、商品データを一度に取得する複雑なクエリの例を紹介します。
// ...(前述のコードと同様のimport文)
type CustomerOrder struct {
CustomerID int `db:"customer_id" json:"customer_id"`
Orders []Order `db:"orders" json:"orders"`
}
func main() {
// ...(前述のDB接続コード)
http.HandleFunc("/customer-orders", func(w http.ResponseWriter, r *http.Request) {
var customerOrders []CustomerOrder
query := `
SELECT customers.id as customer_id, json_agg(json_build_object('id', orders.id, 'products', products)) as orders
FROM customers
JOIN orders ON customers.id = orders.customer_id
JOIN order_details ON orders.id = order_details.order_id
JOIN products ON products.id = order_details.product_id
GROUP BY customers.id`
if err := db.Select(&customerOrders, query); err != nil {
log.Fatalln(err)
}
json.NewEncoder(w).Encode(customerOrders)
})
http.ListenAndServe(":8080", nil)
}
完成系
package main
import (
"database/sql"
"encoding/json"
"log"
"net/http"
_ "github.com/lib/pq"
"github.com/jmoiron/sqlx"
)
// 商品データ構造
type Product struct {
ID int `db:"id" json:"id"`
Name string `db:"name" json:"name"`
Price int `db:"price" json:"price"`
}
// 注文データ構造
type Order struct {
ID int `db:"id" json:"id"`
CustomerID int `db:"customer_id" json:"customer_id"`
Products []Product `db:"products" json:"products"`
}
// 顧客とその注文のデータ構造
type CustomerOrder struct {
CustomerID int `db:"customer_id" json:"customer_id"`
Orders []Order `db:"orders" json:"orders"`
}
func main() {
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
if err != nil {
log.Fatalln(err)
}
// 商品データ取得のエンドポイント
http.HandleFunc("/products", func(w http.ResponseWriter, r *http.Request) {
var products []Product
if err := db.Select(&products, "SELECT * FROM products"); err != nil {
log.Fatalln(err)
}
json.NewEncoder(w).Encode(products)
})
// 注文と商品詳細の統合エンドポイント
http.HandleFunc("/orders", func(w http.ResponseWriter, r *http.Request) {
var orders []Order
query := `
SELECT orders.id, orders.customer_id, json_agg(products.*) as products
FROM orders
JOIN order_details ON orders.id = order_details.order_id
JOIN products ON products.id = order_details.product_id
GROUP BY orders.id`
if err := db.Select(&orders, query); err != nil {
log.Fatalln(err)
}
json.NewEncoder(w).Encode(orders)
})
// 顧客と注文の統合エンドポイント
http.HandleFunc("/customer-orders", func(w http.ResponseWriter, r *http.Request) {
var customerOrders []CustomerOrder
query := `
SELECT customers.id as customer_id, json_agg(json_build_object('id', orders.id, 'products', products)) as orders
FROM customers
JOIN orders ON customers.id = orders.customer_id
JOIN order_details ON orders.id = order_details.order_id
JOIN products ON products.id = order_details.product_id
GROUP BY customers.id`
if err := db.Select(&customerOrders, query); err != nil {
log.Fatalln(err)
}
json.NewEncoder(w).Encode(customerOrders)
})
http.ListenAndServe(":8080", nil)
}
まとめ
この記事では、Go言語、PostgreSQL、sqlxライブラリを用いたECアプリケーション開発におけるREST APIの作成方法を紹介しました。商品情報、注文データ、顧客情報を統合して効率的なAPIエンドポイントを構築することで、柔軟かつ効果的なデータ管理が可能になります。これらのテクニックを活用し、高品質なECアプリケーションの開発に役立ててください。