Buka file cmd/api/animeModel.go, lalu ubah isi fungsi Get dengan code dibawah.
Digunakan context untuk mengatur in-progress operation. Lalu buat query string untuk mengambil data anime.
func (m *AnimeModel) Get(id int) (*Anime, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
query := `SELECT id, title, description, year
FROM anime WHERE id = $1
`
row := m.DB.QueryRowContext(ctx, query, id)
var anime Anime
err := row.Scan(
&anime.Id,
&anime.Title,
&anime.Desc,
&anime.Year,
)
if err != nil {
return nil, err
}
return &anime, nil
}
Kemudian ubah fungsi getAnime pada file cmd/api/animesHandler.go
func (app *application) getAnime(rw http.ResponseWriter, r *http.Request) {
params := httprouter.ParamsFromContext(r.Context())
id, err := strconv.Atoi(params.ByName("id"))
if err != nil {
app.logger.Println(errors.New("invalid id"))
app.errorJSON(rw, err)
return
}
app.logger.Println(id)
anime, err := app.models.Animes.Get(id)
err = app.writeJSON(rw, http.StatusOK, anime, "anime")
if err != nil {
app.errorJSON(rw, err)
}
}
Jalankan server dengan perintah go run ./cmd/api/. lalu test untuk api diatas dengan url http://localhost:4000/v1/api/anime/1
Sesuai ekspektasi, api diatas berhasil mengambil data dari database.

Latihan
Sebagai latihan, ubah fungsi Get pada file cmd/api/animeModel.go diatas untuk mendapatkan data genre juga.
Solusi
Pertama, tambahkan dahulu data pada tabel animes_genres, sesuaikan dengan data pada tabel animes dan genres.
Lalu modifikasi fungsi Get pada file cmd/api/animeModel.go dengan menambahkan code dibawah.
query = `SELECT ag.id, ag.anime_id, ag.genre_id, g.genre_name
FROM animes_genres ag
LEFT JOIN genres g ON (g.id = ag.id)
WHERE ag.anime_id = $1
`
rows, _ := m.DB.QueryContext(ctx, query, id)
genre := make(map[int]string)
for rows.Next() {
var ag animeGenre
err := rows.Scan(
&ag.Id,
&ag.AnimeId,
&ag.GenreId,
&ag.Genre.GenreName,
)
if err != nil {
return nil, err
}
genre[ag.Id] = ag.Genre.GenreName
}
anime.AnimeGenre = genre
Jika kita jalankan web app, sesuai ekspektasi, data genre sudah ditampilkan.

Berikut isi lengkap code file cmd/api/animeHandlers.go
package main
import (
"errors"
"net/http"
"strconv"
"github.com/julienschmidt/httprouter"
)
func (app *application) getAnime(rw http.ResponseWriter, r *http.Request) {
params := httprouter.ParamsFromContext(r.Context())
id, err := strconv.Atoi(params.ByName("id"))
if err != nil {
app.logger.Println(errors.New("invalid id"))
app.errorJSON(rw, err)
return
}
app.logger.Println(id)
anime, err := app.models.Animes.Get(id)
err = app.writeJSON(rw, http.StatusOK, anime, "anime")
if err != nil {
app.errorJSON(rw, err)
}
}
func (app *application) getAnimes(rw http.ResponseWriter, r *http.Request) {
}
isi lengkap code file cmd/api/animeModel.go
package models
import (
"context"
"database/sql"
"time"
)
type AnimeModel struct {
DB *sql.DB
}
func (m *AnimeModel) Get(id int) (*Anime, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
query := `SELECT id, title, description, year
FROM animes WHERE id = $1
`
row := m.DB.QueryRowContext(ctx, query, id)
var anime Anime
err := row.Scan(
&anime.Id,
&anime.Title,
&anime.Desc,
&anime.Year,
)
if err != nil {
return nil, err
}
query = `SELECT ag.id, ag.anime_id, ag.genre_id, g.genre_name
FROM animes_genres ag
LEFT JOIN genres g ON (g.id = ag.id)
WHERE ag.anime_id = $1
`
rows, _ := m.DB.QueryContext(ctx, query, id)
genre := make(map[int]string)
for rows.Next() {
var ag animeGenre
err := rows.Scan(
&ag.Id,
&ag.AnimeId,
&ag.GenreId,
&ag.Genre.GenreName,
)
if err != nil {
return nil, err
}
genre[ag.Id] = ag.Genre.GenreName
}
anime.AnimeGenre = genre
return &anime, nil
}
func (m *AnimeModel) All() ([]*Anime, error) {
return nil, nil
}