How to get header data of postman using gin package in golang - go

I want to get the header data using gin package(golang) in the postman but I don't get any idea how to do it. I search it for google but not getting any answer. Can anyone help me to get the data from the postman header the data I want to get is shown in image.
Image:-

You can get the token header with c.Request.Header["Token"].
Here is a sample code.
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/test", func(c *gin.Context) {
c.JSON(200, gin.H{
"token_data": c.Request.Header["Token"],
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}
Here is an example screenshot of postman.

I use this code and work well
func getProduct(c *gin.Context) {
token := strings.Split(c.Request.Header["Authorization"][0], " ")[1]
c.JSON(200, gin.H{"result": "get product", "token": token})
}
Here is the test data
GET http://localhost:8081/api/v2/product HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTg4OTI4NzY0LCJleHAiOjE1ODg5MzM3NjR9.GrPK-7uEsfpdAYamoqaDFclYwTZ3LOlspoEXUORfSuY

Instead of accessing request object directly, gin provides a getter (easier to use and makes code cleaner). Based on #Shiva accepted answer:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/test", func(c *gin.Context) {
c.JSON(200, gin.H{
// or c.GetHeader("Authorization")
"token_data": c.GetHeader("Token"),
})
})
r.Run() // listen and serve on 0.0.0.0:8080
}

Related

Why Fiber duplicate GET endpoint whith a HEAD endpoint

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.

Is there a way to make CORS work for a single route in Gin Go

I am trying to make a single gin server endpoint be accessible by a certain origin. I have tried some packages such as https://github.com/gin-contrib/cors but from what I understand it sets CORS to your whole server.
For example I have multiple routes but I only want "/scrape" to be allowed to be accessed by "google.com"
/data "all origins"
/ping "all origins"
/scrape "google.com"
Of course you can. It(https://github.com/gin-contrib/cors) just a middleware.
package main
import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// CORS for example.com and example.net origins
router.Use(cors.New(cors.Config{
AllowOrigins: []string{"example.com"},
AllowOriginFunc: func(origin string) bool {
return origin == "example.net"
}})).GET("/scrape", func(c *gin.Context) {
// serve something
})
allOrigins := router.Group("/")
allOrigins.Use(cors.Default())
allOrigins.GET("/data", func(c *gin.Context) {
// serve something
})
allOrigins.GET("/ping", func(c *gin.Context) {
// serve something
})
router.Run()
}
See more middleware example: https://github.com/gin-gonic/gin#using-middleware

Graphql Subscriptions not working with Gin

When I tried to setup a Go web server with GraphQL I used this as template. It is basically a combo of gin and 99designs/gqlgen.
When I create a basic gqlgen server based on net/http package, the declaration of GraphQL subscriptions work as expected.
package main
import (
"log"
"net/http"
"os"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/jawil003/gqlgen/graph"
"github.com/jawil003/gqlgen/graph/generated"
)
const defaultPort = "8080"
func main() {
port := os.Getenv("PORT")
if port == "" {
port = defaultPort
}
srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))
http.Handle("/", playground.Handler("GraphQL playground", "/query"))
http.Handle("/query", srv)
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
But when I add gin, like this:
package main
import (
"github.com/gin-gonic/gin"
"github.com/jawil003/gqlgen-todos/graph"
"github.com/jawil003/gqlgen-todos/graph/generated"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground"
)
// Defining the Graphql handler
func graphqlHandler() gin.HandlerFunc {
// NewExecutableSchema and Config are in the generated.go file
// Resolver is in the resolver.go file
h := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))
return func(c *gin.Context) {
h.ServeHTTP(c.Writer, c.Request)
}
}
// Defining the Playground handler
func playgroundHandler() gin.HandlerFunc {
h := playground.Handler("GraphQL", "/query")
return func(c *gin.Context) {
h.ServeHTTP(c.Writer, c.Request)
}
}
func main() {
// Setting up Gin
r := gin.Default()
r.POST("/query", graphqlHandler())
r.GET("/", playgroundHandler())
r.Run()
}
I get this issue:
{ "error": "Could not connect to websocket endpoint ws://localhost:8080/query. Please check if the endpoint url is correct." }
Is there any known solution to make gin work with graphql subscriptions?
Hello to fix error Could not connect to websocket endpoint.. with Gin change r.POST("/query", graphqlHandler()) to r.Any("/query", graphqlHandler())

How do I get the body that was sent? Using gin gonic

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.

Gin binding middleware always fail

Im trying to have custom error messages for gin validation & followed the advice in this thread: https://github.com/gin-gonic/gin/issues/430
Im trying the gin binding midddleware this way:
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
type itemPostRequest struct {
Name string `json:"name" binding:"required"`
}
func main() {
router := gin.Default()
router.Use(func (c *gin.Context) {
c.Next()
fmt.Println(c.Errors)
})
router.POST("/item", gin.Bind(itemPostRequest{}), func (c *gin.Context) {
fmt.Println("Im inside handler")
req := c.MustGet(gin.BindKey).(*itemPostRequest)
fmt.Println(req)
c.JSON(http.StatusOK, gin.H{"success": true})
})
router.Run()
}
I send the request using Postman but although I have sent the correct request, it always say:
Key: 'itemPostRequest.Name' Error:Field validation for 'Name' failed on the 'required' tag
If I don't use the binding middleware:
router.POST("/item", func (c *gin.Context) {
...
It works but i want to be able to bind and return error before I go to the handler, just like the advice on the thread. Why is this not working? Thank you
thx to the comment, I realized I missed Content-Type application/json. I didn't realize this because I used c.ShouldBindWithJSON before and it didnt need this header.

Resources