So I try to write code for handle func to router. But I get the error message like this "cannot use controller.UserController.FindAll (value of type func(_ controller.UserController, c *fiber.Ctx) error) as type func(*fiber.Ctx) error in argument to app.Get"
this the code.
package route
package route
import (
"go_fiber/controller"
"github.com/gofiber/fiber/v2"
)
func RouteInit(app *fiber.App) {
app.Get("/users", controller.UserController.FindAll ) //this line is error
}
package controller
package controller
import (
"go_fiber/model/web"
"go_fiber/service"
"github.com/gofiber/fiber/v2"
)
type UserController interface{
// Create(c *fiber.Ctx)
// Update(c *fiber.Ctx)
FindAll(c *fiber.Ctx) error
// FindById(c *fiber.Ctx)
// Delete(c *fiber.Ctx)
}
type UserControllerImpl struct {
UserService service.UserService
}
func NewUserController(UserService service.UserService) UserController {
return &UserControllerImpl{
UserService: UserService,
}
}
func (controller *UserControllerImpl) FindAll(c *fiber.Ctx) error {
userResponse := controller.UserService.FindAll(c)
webResponse := web.WebResponse{
Code: 200,
Status: "success",
Data: userResponse,
}
c.JSON(webResponse)
return nil
}
How to fix it?
EDIT
So this is solve. This code the solve code
package main
package main
import (
"go_fiber/app"
"go_fiber/controller"
"go_fiber/repository"
"go_fiber/route"
"go_fiber/service"
"github.com/gofiber/fiber/v2"
)
func main(){
db := app.NewDB()
app.CreateDatabase(db)
app := fiber.New()
userRepository := repository.NewUserRepository()
userService := service.NewUserService(userRepository, db)
userController := controller.NewUserController(userService)
route.RouteInit(app, userController)
app.Listen(":3000")
}
package route
package route
import (
"go_fiber/controller"
"github.com/gofiber/fiber/v2"
)
func RouteInit(app *fiber.App, userController controller.UserController) {
app.Get("/users", userController.FindAll)
}
Related
these is my api and i don't know what is the problem for that endpoints duplicated, i was trying if is something of config but there is not nothing about in their documentation
package main
import (
"aurora/routes"
"fmt"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New(fiber.Config{
AppName: "Aurora Api V1",
})
routes.ServerRoutes(app)
app.Get("/AAAAAAAA", func(c *fiber.Ctx) error {
return c.JSON("hellow from login")
})
routesList := app.GetRoutes()
for i, route := range routesList {
fmt.Printf("%d - %d\n", i+1, route)
}
app.Listen(":3000")
}
package routes
import (
"aurora/routes/user"
"github.com/gofiber/fiber/v2"
)
func ServerRoutes(server *fiber.App) {
user.UserRoutes(server.Group("/user"))
}
package user
import "github.com/gofiber/fiber/v2"
func UserRoutes(router fiber.Router) {
router.Get("/login", func(c *fiber.Ctx) error {
return c.JSON("hellow from login")
})
router.Get("/logout", func(c *fiber.Ctx) error {
return c.JSON("hellow from logout")
})
router.Get("/signup", func(c *fiber.Ctx) error {
return c.JSON("hellow from signup")
})
}
i want that golang just map GET endpoints not HEAD endpoints, or there a reason for that?
I think HEAD method is used as default for GET routes in Fiber since it's nearly the same thing. Read more about HEAD method in MDN Docs.
I am writing a simple rest api using echo framework for route handling. I am trying to maintain centralised error handling using middlewares. In the following code, in the error method implementation I want to return a struct so that I can use that info in custom error Handler
main.go
package main
import log "github.com/sirupsen/logrus"
import "github.com/labstack/echo"
import "net/http"
import "fmt"
func main(){
e := echo.New()
e.GET("process", PostHandler)
e.HTTPErrorHandler = customHTTPErrorHandler
log.Fatal(e.Start(":3000"))
}
func PostHandler(ctx echo.Context) error{
x:= 0;
if x != 0 {
return NewTypeError(1024, "Invalid arguments")
}
return ctx.JSON(http.StatusOK, "message")
}
func customHTTPErrorHandler(err error, c echo.Context) {
fmt.Println("Inside custom error")
fmt.Println(err);
}
error.go
package main
import "fmt"
type Error struct{
Message string
Internal int
}
func (e *Error)Error() string{
fmt.Println("Hello error")
return "error"
}
func NewTypeError( Internal int, Message string) *Error {
fmt.Println(Internal)
fmt.Println(Message)
return &Error{
Message,
Internal,
}
}
I want my output json response to be sent from custom error middleware like this.
{
code: "1024",
message: "Invalid Arguments"
}
Add c.JSON to customHTTPErrorHandler and add json tags to struct Error.
// main.go
package main
import (
"fmt"
"net/http"
"github.com/labstack/echo"
log "github.com/sirupsen/logrus"
)
func main() {
e := echo.New()
e.GET("process", PostHandler)
e.HTTPErrorHandler = customHTTPErrorHandler
log.Fatal(e.Start(":3000"))
}
func PostHandler(ctx echo.Context) error {
x := 0
if x == 0 {
return NewTypeError(http.StatusInternalServerError, 1024, "Invalid arguments")
}
return ctx.JSON(http.StatusOK, "message")
}
func customHTTPErrorHandler(err error, c echo.Context) {
fmt.Println("Inside custom error")
var rerr *Error
switch e := err.(type) {
case *Error:
rerr = e
case *echo.HTTPError:
// todo: improve error conversion
rerr = NewTypeError(e.Code, EchoHttpError, e.Error())
default:
rerr = NewTypeError(http.StatusInternalServerError, InternalError, e.Error())
}
c.JSON(rerr.Code, rerr)
}
// error.go
package main
import (
"fmt"
)
const (
EchoHttpError int = iota
InternalError
)
type Error struct {
Code int `json:"-"` // optional
Message string `json:"message"`
Internal int `json:"internal"`
}
func (e *Error) Error() string {
fmt.Println("Hello error")
return "error"
}
func NewTypeError(code int, internal int, message string) *Error {
fmt.Println(internal)
fmt.Println(message)
return &Error{
Code: code,
Message: message,
Internal: internal,
}
}
you should insert model on argument.
and u should make variable response, same with struct.
if u show code on response, u should add code on error struct.
func ToErrorResponse(err model.Error) *ErrorResponse {
errorResponse := &ErrorResponse{
code: err.Code,
message: err.Message,
}
return errorResponse
}
and call function.
I want to make seperate files for each sub main routes. I am using go 1.17
main.go
package main
import (
"rolling_glory_go/routes"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) error {
err := c.SendString("Hello golang!")
return err
})
routes.R_login(app.Group("/login"))
routes.R_users(app.Group("/users"))
app.Listen(":3000")
}
I want to import routes from r_login.go and r_users.go so i could manage many routes from different files and not put many routes from single file in main.go. I got an error like this.
.\main.go:17:26: cannot use app.Group("/login") (type fiber.Router) as type *fiber.Group in argument to routes.R_login: need type assertion
.\main.go:18:26: cannot use app.Group("/users") (type fiber.Router) as type *fiber.Group in argument to routes.R_users: need type assertion
My Structure Folder
r_login.go
package routes
import "github.com/gofiber/fiber/v2"
func R_login(router *fiber.Group) {
router.Get("/", func(c *fiber.Ctx) error {
return c.SendString("respond with a resource")
})
}
r_users.go
package routes
import "github.com/gofiber/fiber/v2"
func R_users(router *fiber.Group) {
router.Get("/", func(c *fiber.Ctx) error {
return c.SendString("respond with a resource")
})
}
How to fix this ?
As you have app.Group("/login") which of type fiber.Router
, just modify R_login to have it accept this type.
package routes
import "github.com/gofiber/fiber/v2"
func R_login(router fiber.Router) {
router.Get("/", func(c *fiber.Ctx) error {
return c.SendString("respond with a resource")
})
}
How do I get the body that was sent?
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
fmt.Println("Hello, world!")
r := gin.Default()
r.POST("/", func(c *gin.Context) {
body := c.Request.Body
c.JSON(200,body);
})
r.Run(":8080");
}
I make a request via postman
{
"email": "test#gmail.com",
"password": "test"
}
and in response I get empty json {}
what to do?
You can bind the incoming request json as follows:
package main
import (
"github.com/gin-gonic/gin"
)
type LoginReq struct {
Email string
Password string
}
func main() {
r := gin.Default()
r.POST("/", func(c *gin.Context) {
var req LoginReq
c.BindJSON(&req)
c.JSON(200, req)
})
r.Run(":8080")
}
Remember this method gives 400 if there is a binding error. If you want to handle error yourself, try ShouldBindJSON which returns an error if any or nil.
I have two files main.go and group.go... it looks something like this
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
// Creates a gin router with default middlewares:
// logger and recovery (crash-free) middlewares
router := gin.Default()
v1 := router.Group("/v1")
{
v1.GET("/", func (c *gin.Context) {
c.JSON(http.StatusOK, "{'sup': 'dup'}")
})
groups := v1.Group("/groups")
{
groups.GET("/", groupIndex)
groups.GET("/:id", groupShow)
groups.POST("/", groupCreate)
groups.PUT("/:id", groupUpdate)
groups.DELETE("/:id", groupDelete)
}
}
// Listen and server on 0.0.0.0:8080
router.Run(":3000")
}
So the methods groupIndex, groupCreate, groupUpdate, etc are located in another file under routes/group.go
package main
import (
"strings"
"github.com/gin-gonic/gin"
)
func groupIndex(c *gin.Context) {
var group struct {
Name string
Description string
}
group.Name = "Famzz"
group.Description = "Jamzzz"
c.JSON(http.StatusOK, group)
}
func groupShow(c *gin.Context) {
c.JSON(http.StatusOK, "{'groupShow': 'someContent'}")
}
func groupCreate(c *gin.Context) {
c.JSON(http.StatusOK, "{'groupShow': 'someContent'}")
}
func groupUpdate(c *gin.Context) {
c.JSON(http.StatusOK, "{'groupUpdate': 'someContent'}")
}
func groupDelete(c *gin.Context) {
c.JSON(http.StatusOK, "{'groupDelete': 'someContent'}")
}
But when I try to compile I get the following error
stuff/main.go:21: undefined: groupIndex
stuff/main.go:23: undefined: groupShow
stuff/main.go:24: undefined: groupCreate
stuff/main.go:25: undefined: groupUpdate
stuff/main.go:26: undefined: groupDelete
I'm super new to go, but I thought if you put files in the same package, then they'll have access to each other. What am I doing wrong here?
There are two ways to fix this:
Move group.go to the same directory as main.go.
Import group.go as a package. Change the package declaration on group.go to:
package routes // or the name of your choice
Export the functions by starting them with a capital letter:
func GroupIndex(c *gin.Context) {
Import the package from main:
import "path/to/routes"
...
groups.GET("/", routes.GroupIndex)
The document How To Write Go Code explains this and more.