Potentially not an issue, might just be something I can't figure out how to do. ODATA specification states that you should be able to query a single resources using its ID by using an endpoint like
r.GET("/odata/Resource(:id)", QuerySingleResource)
I'm having trouble getting that to work though, the ID doesn't come through in the url parameters, nor is it a query parameter.
var id = c.Param("id")
var queryString = c.Request.URL.Query()
fmt.Println(queryString)
fmt.Println(id)
prints out
map[]
Any ideas how it works?
It finds the route correctly, and I can print out the path with the ID, which I suppose I could parse out of the path, but it seems like I should be able to pull it out with c.Param("id")
Comment From: alifemove
I figured it out and it is an issue it seems.
In order to pull the parameter when you do this you have to use
c.Param("id)")
For some reason it includes the ) as part of the parameter name, as well it also adds ) to the end of the value of the parameter...
Comment From: RodEspinoza
🤔 looks like the endpoint route definition its pretty weird, maybe if you try something like this based in the documentation, obviously if you write the de defition of the url.
try passing from
r.GET("/odata/Resource(:id)", QuerySingleResource)
to this :
r.GET("/odata/Resource/:id", QuerySingleResource)
Comment From: alifemove
@RodEspinoza Thats not really possible. The ODATA standard specifies it should be /Resource(:id)
and the tests that I have to run against the API for certification require it that way.
Comment From: RedCrazyGhost
The ODATA protocol may look a little strange.
The following code is a general practice.
r.GET("/odata/Resource:id", func(c *gin.Context) {
param := c.Param("id")
c.String(http.StatusOK, param)
})
curl 'http://127.0.0.1:8080/odata/Resource2' >>> 2
curl 'http://127.0.0.1:8080/odata/Resource2/23' >>> not found
curl 'http://127.0.0.1:8080/odata/Resource2?abc' >>> 2
if you want to achieve the results you want to see the answer below
Comment From: RodEspinoza
🤔 based in odata, maybe you can try with regex to extract the param : if this works maybe you can try to generate a pull requests with the function 👀
this maybe could help :
package main
import (
"fmt"
"regexp"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/odata/Resource(:id)", QuerySingleResource)
r.Run(":8080")
}
// maybe you can generate a middleware to extract params based in odata format, that return a map or somethign required
func QuerySingleResource(c *gin.Context) {
// Get the part of the URL that contains the :id parameter
urlPart := c.Param("id")
// Use regular expressions to extract the value between parentheses
re := regexp.MustCompile(`\((.*?)\)`)
matches := re.FindStringSubmatch(urlPart)
if len(matches) < 2 {
c.JSON(400, gin.H{"error": "No valid value found for :id"})
return
}
// The extracted value is in matches[1]
id := matches[1]
c.JSON(200, gin.H{"id": id})
}
Comment From: RedCrazyGhost
🤔 基于 odata,也许你可以尝试使用正则表达式来提取参数: 如果这有效,也许你可以尝试使用函数 👀 生成拉取请求
这也许会有所帮助:
包主
``` import ( "fmt" "regexp"
"github.com/gin-gonic/gin" )
func main() { r := gin.Default()
r.GET("/odata/Resource(:id)", QuerySingleResource)
r.Run(":8080") }
// maybe you can generate a middleware to extract params based in odata format, that return a map or somethign required
func QuerySingleResource(c *gin.Context) { // Get the part of the URL that contains the :id parameter urlPart := c.Param("id")
// Use regular expressions to extract the value between parentheses re := regexp.MustCompile(
\((.*?)\)
) matches := re.FindStringSubmatch(urlPart)if len(matches) < 2 { c.JSON(400, gin.H{"error": "No valid value found for :id"}) return }
// The extracted value is in matches[1] id := matches[1]
c.JSON(200, gin.H{"id": id}) } ```
Hi,urlPart := c.Param("id") in your code does not match to get data
@alifemove Can try
r.GET("/odata/Resource:(id)", func(c *gin.Context) {
param := c.Param("(id)")
ID := param[1:len(param)-1]
c.String(http.StatusOK, ID)
})
Comment From: alifemove
@RedCrazyGhost Yeah I think that would be the easiest approach given the circumstance.
I think the underlying issue is using : to signify variables and allowing any valid url character as part of the variable even though you can't name a variable with () in code. Using { } like mux and other routers do is the safer bet since the variable has a definitive beginning and end.