mirror of
https://github.com/gin-gonic/gin.git
synced 2026-09-04 14:49:27 +08:00
Merge e0ae9100ca8a0062489b78ec34f203c2f5d43d1a into dcaa4296d111981ffb31ac3eba90bb63e1eb5ab9
This commit is contained in:
commit
22bef8fd14
19
docs/doc.md
19
docs/doc.md
@ -6,7 +6,8 @@
|
||||
- [Build with json replacement](#build-with-json-replacement)
|
||||
- [Build without MsgPack rendering feature](#build-without-msgpack-rendering-feature)
|
||||
- [Routing](#routing)
|
||||
- [Using GET, POST, PUT, PATCH, DELETE and OPTIONS](#using-get-post-put-patch-delete-and-options)
|
||||
- [Using GET, POST, PUT, PATCH, QUERY, DELETE and OPTIONS](#using-get-post-put-patch-delete-query-and-options)
|
||||
- [QUERY Method (RFC 10008)](#query-method-rfc-10008)
|
||||
- [Parameters in path](#parameters-in-path)
|
||||
- [Querystring parameters](#querystring-parameters)
|
||||
- [Multipart/Urlencoded Form](#multiparturlencoded-form)
|
||||
@ -114,7 +115,7 @@ This is useful to reduce the binary size of executable files. See the [detail in
|
||||
|
||||
> Learn how to define routes, handle parameters, and organize endpoints.
|
||||
|
||||
### Using GET, POST, PUT, PATCH, DELETE and OPTIONS
|
||||
### Using GET, POST, PUT, PATCH, DELETE, QUERY and OPTIONS
|
||||
|
||||
```go
|
||||
func main() {
|
||||
@ -127,6 +128,7 @@ func main() {
|
||||
router.PUT("/somePut", putting)
|
||||
router.DELETE("/someDelete", deleting)
|
||||
router.PATCH("/somePatch", patching)
|
||||
router.QUERY("/someQuery", querying)
|
||||
router.HEAD("/someHead", head)
|
||||
router.OPTIONS("/someOptions", options)
|
||||
|
||||
@ -136,6 +138,19 @@ func main() {
|
||||
// router.Run(":3000") for a hard coded port
|
||||
}
|
||||
```
|
||||
### QUERY Method (RFC 10008)
|
||||
|
||||
Gin supports the HTTP `QUERY` method defined by RFC 10008.
|
||||
|
||||
```go
|
||||
router.QUERY("/search", querying)
|
||||
```
|
||||
|
||||
The exported `gin.MethodQuery` constant can be used wherever an HTTP method is required, such as when constructing requests:
|
||||
|
||||
```go
|
||||
req := httptest.NewRequest(gin.MethodQuery, "/query", nil)
|
||||
```
|
||||
|
||||
### Parameters in path
|
||||
|
||||
|
||||
@ -67,6 +67,11 @@ func GET(relativePath string, handlers ...gin.HandlerFunc) gin.IRoutes {
|
||||
return engine().GET(relativePath, handlers...)
|
||||
}
|
||||
|
||||
// QUERY is a shortcut for router.Handle("QUERY", path, handle)
|
||||
func QUERY(relativePath string, handlers ...gin.HandlerFunc) gin.IRoutes {
|
||||
return engine().QUERY(relativePath, handlers...)
|
||||
}
|
||||
|
||||
// DELETE is a shortcut for router.Handle("DELETE", path, handle)
|
||||
func DELETE(relativePath string, handlers ...gin.HandlerFunc) gin.IRoutes {
|
||||
return engine().DELETE(relativePath, handlers...)
|
||||
|
||||
@ -31,6 +31,19 @@ func TestGET(t *testing.T) {
|
||||
assert.Equal(t, "test", w.Body.String())
|
||||
}
|
||||
|
||||
func TestQUERY(t *testing.T) {
|
||||
QUERY("/query", func(c *gin.Context) {
|
||||
c.String(http.StatusOK, "query")
|
||||
})
|
||||
|
||||
req := httptest.NewRequest(gin.MethodQuery, "/query", nil)
|
||||
w := httptest.NewRecorder()
|
||||
engine().ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "query", w.Body.String())
|
||||
}
|
||||
|
||||
func TestPOST(t *testing.T) {
|
||||
POST("/post", func(c *gin.Context) {
|
||||
c.String(http.StatusCreated, "created")
|
||||
|
||||
@ -11,6 +11,9 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MethodQuery is the HTTP QUERY method defined by RFC 10008.
|
||||
const MethodQuery = "QUERY"
|
||||
|
||||
var (
|
||||
// regEnLetter matches english letters for http method name
|
||||
regEnLetter = regexp.MustCompile("^[A-Z]+$")
|
||||
@ -19,7 +22,7 @@ var (
|
||||
anyMethods = []string{
|
||||
http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch,
|
||||
http.MethodHead, http.MethodOptions, http.MethodDelete, http.MethodConnect,
|
||||
http.MethodTrace,
|
||||
http.MethodTrace, MethodQuery,
|
||||
}
|
||||
)
|
||||
|
||||
@ -36,6 +39,7 @@ type IRoutes interface {
|
||||
Handle(string, string, ...HandlerFunc) IRoutes
|
||||
Any(string, ...HandlerFunc) IRoutes
|
||||
GET(string, ...HandlerFunc) IRoutes
|
||||
QUERY(string, ...HandlerFunc) IRoutes
|
||||
POST(string, ...HandlerFunc) IRoutes
|
||||
DELETE(string, ...HandlerFunc) IRoutes
|
||||
PATCH(string, ...HandlerFunc) IRoutes
|
||||
@ -117,6 +121,11 @@ func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRou
|
||||
return group.handle(http.MethodGet, relativePath, handlers)
|
||||
}
|
||||
|
||||
// QUERY is a shortcut for router.Handle("QUERY", path, handlers).
|
||||
func (group *RouterGroup) QUERY(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle(MethodQuery, relativePath, handlers)
|
||||
}
|
||||
|
||||
// DELETE is a shortcut for router.Handle("DELETE", path, handlers).
|
||||
func (group *RouterGroup) DELETE(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
return group.handle(http.MethodDelete, relativePath, handlers)
|
||||
@ -143,7 +152,7 @@ func (group *RouterGroup) HEAD(relativePath string, handlers ...HandlerFunc) IRo
|
||||
}
|
||||
|
||||
// Any registers a route that matches all the HTTP methods.
|
||||
// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.
|
||||
// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE, QUERY.
|
||||
func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes {
|
||||
for _, method := range anyMethods {
|
||||
group.handle(method, relativePath, handlers)
|
||||
|
||||
@ -42,6 +42,7 @@ func TestRouterGroupBasicHandle(t *testing.T) {
|
||||
performRequestInGroup(t, http.MethodDelete)
|
||||
performRequestInGroup(t, http.MethodHead)
|
||||
performRequestInGroup(t, http.MethodOptions)
|
||||
performRequestInGroup(t, MethodQuery)
|
||||
}
|
||||
|
||||
func performRequestInGroup(t *testing.T, method string) {
|
||||
@ -78,6 +79,9 @@ func performRequestInGroup(t *testing.T, method string) {
|
||||
case http.MethodOptions:
|
||||
v1.OPTIONS("/test", handler)
|
||||
login.OPTIONS("/test", handler)
|
||||
case MethodQuery:
|
||||
v1.QUERY("/test", handler)
|
||||
login.QUERY("/test", handler)
|
||||
default:
|
||||
panic("unknown method")
|
||||
}
|
||||
@ -182,6 +186,7 @@ func testRoutesInterface(t *testing.T, r IRoutes) {
|
||||
assert.Equal(t, r, r.Handle(http.MethodGet, "/handler", handler))
|
||||
assert.Equal(t, r, r.Any("/any", handler))
|
||||
assert.Equal(t, r, r.GET("/", handler))
|
||||
assert.Equal(t, r, r.QUERY("/", handler))
|
||||
assert.Equal(t, r, r.POST("/", handler))
|
||||
assert.Equal(t, r, r.DELETE("/", handler))
|
||||
assert.Equal(t, r, r.PATCH("/", handler))
|
||||
|
||||
@ -116,6 +116,7 @@ func TestRouterGroupRouteOK(t *testing.T) {
|
||||
testRouteOK(http.MethodDelete, t)
|
||||
testRouteOK(http.MethodConnect, t)
|
||||
testRouteOK(http.MethodTrace, t)
|
||||
testRouteOK(MethodQuery, t)
|
||||
}
|
||||
|
||||
func TestRouteNotOK(t *testing.T) {
|
||||
@ -128,6 +129,7 @@ func TestRouteNotOK(t *testing.T) {
|
||||
testRouteNotOK(http.MethodDelete, t)
|
||||
testRouteNotOK(http.MethodConnect, t)
|
||||
testRouteNotOK(http.MethodTrace, t)
|
||||
testRouteNotOK(MethodQuery, t)
|
||||
}
|
||||
|
||||
func TestRouteNotOK2(t *testing.T) {
|
||||
@ -140,6 +142,7 @@ func TestRouteNotOK2(t *testing.T) {
|
||||
testRouteNotOK2(http.MethodDelete, t)
|
||||
testRouteNotOK2(http.MethodConnect, t)
|
||||
testRouteNotOK2(http.MethodTrace, t)
|
||||
testRouteNotOK2(MethodQuery, t)
|
||||
}
|
||||
|
||||
func TestRouteRedirectTrailingSlash(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user