I'm trying to write a restful api on golang. For http router I use gin-gonic, to interact with the database I use gorm. package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
var db *gorm.DB
type Person struct {
ID uint `json:"id"`
FirstName string `json:"firstname"`
LastName string `json:"lastname"`
}
func main() {
// NOTE: See we’re using = to assign the global var
// instead of := which would assign it only in this function
db, err := gorm.Open("postgres", fmt.Sprintf("host=localhost sslmode=disable user=postgres password="))
if err != nil {
fmt.Println(err)
}
defer db.Close()
db.AutoMigrate(&Person{})
r := gin.Default()
r.GET("/people/", GetPeople)
r.GET("/people/:id", GetPerson)
r.POST("/people", CreatePerson)
r.Run(":8080")
}
func CreatePerson(c *gin.Context) {
var person Person
c.BindJSON(&person)
db.Create(&person)
c.JSON(200, person)
}
func GetPerson(c *gin.Context) {
id := c.Params.ByName("id")
var person Person
if err := db.Where("id = ?", id).First(&person).Error; err != nil {
c.AbortWithStatus(404)
fmt.Println(err)
} else {
c.JSON(200, person)
}
}
func GetPeople(c *gin.Context) {
var people []Person
if err := db.Find(&people).Error; err != nil {
c.AbortWithStatus(404)
fmt.Println(err)
} else {
c.JSON(200, people)
}
}
How do I split the code into multiple files so that a separate resource is in a separate file? How to use the router and database in another file?
UPDATE
With structure like this:
.
└── app
├── users.go
├── products.go
└── main.go
I have 2 problems:
- db == nil in
products.go
andusers.go
- Redeclaration function (
get
,create
...) in different files, this solve by prefix in function declaration likeCreateUser
,CreateProduct
, etc. But it may be solved by put code into another packages
main.go
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
var (
db *gorm.DB
r *gin.Engine
)
func init() {
db, err := gorm.Open("postgres", fmt.Sprintf("host=localhost sslmode=disable user=postgres password="))
if err != nil {
fmt.Println(err)
}
defer db.Close()
r = gin.Default()
}
func main() {
r.Run(":8080")
}
products.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
)
type Product struct {
gorm.Model
Code string
Price uint
}
func init() {
db.AutoMigrate(&Product{}) // db -> nil
r.GET("/products", get)
}
func get(c *gin.Context) {
var product Product
db.First(&product, 1)
c.JSON(200, gin.H{
"product": product,
})
}
users.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
)
type User struct {
gorm.Model
Name string
}
func init() {
db.AutoMigrate(&User{}) // db -> nil
r.GET("/users", get)
}
// ./users.go:19: get redeclared in this block
// previous declaration at ./products.go:20
func get(c *gin.Context) {
var user User
db.First(&user, 1)
c.JSON(200, gin.H{
"user": user,
})
}