Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

How to call Interface function in go-gin?

This is repository + controller

package brand

import (
    "path/to/models"
    "gorm.io/gorm"

    "github.com/gin-gonic/gin"
)

type ResponseBrand struct {
    Items      []models.MasterBrand `json:"items"`
    TotalCount int                  `json:"total"`
}

type Repository interface {
    GetAll() (ResponseBrand, error)
}

type DBRepo struct {
    db *gorm.DB
}


func (repo *DBRepo) GetAll() (ResponseBrand, error) {
    var response ResponseBrand
    var brands []models.MasterBrand

    repo.db.Find(&brands)

    response.Items = brands
    response.TotalCount = len(brands)

    return response, nil
}

func list(c *gin.Context) {
    // this is an error
    res, _ := Repository.GetAll()
}

This for routing group

func ApplyRoutes(r *gin.RouterGroup) {
    brand := r.Group("/brand") {
        brand.GET("/", list)
    }
}

I try to implement repository in my project, but still stuck to call Repository.GetAll() in our controller function list. i use gin & gorm for this

question from:https://stackoverflow.com/questions/65660925/how-to-call-interface-function-in-go-gin

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Interface is just a set of method signatures that type must have in order to implement that particular interface. So you can't call interface.

In your example code DBRepo is supposed to implement Repository interface and function list() is a function that allows to list contents of any type that implements Repository. In to do so obviously list() needs to know which instance of Repository-like type to list - e.g. receive it as an argument. Like this:

func list(ctx *gin.Context, repo Repository) {
    // here call GetAll() which MUST exist on all types passed (otherwise they don't
    // implement Repository interface
    res, _ := repo.GetAll()
    // ...
}

Now gin wouldn't be able to take modified list as a router function because signature of such is just (ctx *gin.Context) but you can use anonymous function and wrap your Repository-aware list() in it.

func ApplyRoutes(repo Repository, r *gin.RouterGroup) {
    brand := r.Group("/brand") {
        brand.GET("/", func(ctx *gin.Context) {
            list(repo)
        })
    }
}

Also your ApplyRoutes() function needs to know on which Repository routes should operate - I added it here as argument for simplicity, other elegant solution would be to wrap entire controller in type and obtain the Repository instance as a field of receiver.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...