group.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
  2. // 🤖 Github Repository: https://github.com/gofiber/fiber
  3. // 📌 API Documentation: https://docs.gofiber.io
  4. package fiber
  5. import (
  6. "fmt"
  7. "reflect"
  8. )
  9. // Group struct
  10. type Group struct {
  11. app *App
  12. parentGroup *Group
  13. name string
  14. anyRouteDefined bool
  15. Prefix string
  16. }
  17. // Name Assign name to specific route or group itself.
  18. //
  19. // If this method is used before any route added to group, it'll set group name and OnGroupNameHook will be used.
  20. // Otherwise, it'll set route name and OnName hook will be used.
  21. func (grp *Group) Name(name string) Router {
  22. if grp.anyRouteDefined {
  23. grp.app.Name(name)
  24. return grp
  25. }
  26. grp.app.mutex.Lock()
  27. if grp.parentGroup != nil {
  28. grp.name = grp.parentGroup.name + name
  29. } else {
  30. grp.name = name
  31. }
  32. if err := grp.app.hooks.executeOnGroupNameHooks(*grp); err != nil {
  33. panic(err)
  34. }
  35. grp.app.mutex.Unlock()
  36. return grp
  37. }
  38. // Use registers a middleware route that will match requests
  39. // with the provided prefix (which is optional and defaults to "/").
  40. //
  41. // app.Use(func(c *fiber.Ctx) error {
  42. // return c.Next()
  43. // })
  44. // app.Use("/api", func(c *fiber.Ctx) error {
  45. // return c.Next()
  46. // })
  47. // app.Use("/api", handler, func(c *fiber.Ctx) error {
  48. // return c.Next()
  49. // })
  50. //
  51. // This method will match all HTTP verbs: GET, POST, PUT, HEAD etc...
  52. func (grp *Group) Use(args ...interface{}) Router {
  53. var prefix string
  54. var prefixes []string
  55. var handlers []Handler
  56. for i := 0; i < len(args); i++ {
  57. switch arg := args[i].(type) {
  58. case string:
  59. prefix = arg
  60. case []string:
  61. prefixes = arg
  62. case Handler:
  63. handlers = append(handlers, arg)
  64. default:
  65. panic(fmt.Sprintf("use: invalid handler %v\n", reflect.TypeOf(arg)))
  66. }
  67. }
  68. if len(prefixes) == 0 {
  69. prefixes = append(prefixes, prefix)
  70. }
  71. for _, prefix := range prefixes {
  72. grp.app.register(methodUse, getGroupPath(grp.Prefix, prefix), grp, handlers...)
  73. }
  74. if !grp.anyRouteDefined {
  75. grp.anyRouteDefined = true
  76. }
  77. return grp
  78. }
  79. // Get registers a route for GET methods that requests a representation
  80. // of the specified resource. Requests using GET should only retrieve data.
  81. func (grp *Group) Get(path string, handlers ...Handler) Router {
  82. grp.Add(MethodHead, path, handlers...)
  83. return grp.Add(MethodGet, path, handlers...)
  84. }
  85. // Head registers a route for HEAD methods that asks for a response identical
  86. // to that of a GET request, but without the response body.
  87. func (grp *Group) Head(path string, handlers ...Handler) Router {
  88. return grp.Add(MethodHead, path, handlers...)
  89. }
  90. // Post registers a route for POST methods that is used to submit an entity to the
  91. // specified resource, often causing a change in state or side effects on the server.
  92. func (grp *Group) Post(path string, handlers ...Handler) Router {
  93. return grp.Add(MethodPost, path, handlers...)
  94. }
  95. // Put registers a route for PUT methods that replaces all current representations
  96. // of the target resource with the request payload.
  97. func (grp *Group) Put(path string, handlers ...Handler) Router {
  98. return grp.Add(MethodPut, path, handlers...)
  99. }
  100. // Delete registers a route for DELETE methods that deletes the specified resource.
  101. func (grp *Group) Delete(path string, handlers ...Handler) Router {
  102. return grp.Add(MethodDelete, path, handlers...)
  103. }
  104. // Connect registers a route for CONNECT methods that establishes a tunnel to the
  105. // server identified by the target resource.
  106. func (grp *Group) Connect(path string, handlers ...Handler) Router {
  107. return grp.Add(MethodConnect, path, handlers...)
  108. }
  109. // Options registers a route for OPTIONS methods that is used to describe the
  110. // communication options for the target resource.
  111. func (grp *Group) Options(path string, handlers ...Handler) Router {
  112. return grp.Add(MethodOptions, path, handlers...)
  113. }
  114. // Trace registers a route for TRACE methods that performs a message loop-back
  115. // test along the path to the target resource.
  116. func (grp *Group) Trace(path string, handlers ...Handler) Router {
  117. return grp.Add(MethodTrace, path, handlers...)
  118. }
  119. // Patch registers a route for PATCH methods that is used to apply partial
  120. // modifications to a resource.
  121. func (grp *Group) Patch(path string, handlers ...Handler) Router {
  122. return grp.Add(MethodPatch, path, handlers...)
  123. }
  124. // Add allows you to specify a HTTP method to register a route
  125. func (grp *Group) Add(method, path string, handlers ...Handler) Router {
  126. grp.app.register(method, getGroupPath(grp.Prefix, path), grp, handlers...)
  127. if !grp.anyRouteDefined {
  128. grp.anyRouteDefined = true
  129. }
  130. return grp
  131. }
  132. // Static will create a file server serving static files
  133. func (grp *Group) Static(prefix, root string, config ...Static) Router {
  134. grp.app.registerStatic(getGroupPath(grp.Prefix, prefix), root, config...)
  135. if !grp.anyRouteDefined {
  136. grp.anyRouteDefined = true
  137. }
  138. return grp
  139. }
  140. // All will register the handler on all HTTP methods
  141. func (grp *Group) All(path string, handlers ...Handler) Router {
  142. for _, method := range grp.app.config.RequestMethods {
  143. _ = grp.Add(method, path, handlers...)
  144. }
  145. return grp
  146. }
  147. // Group is used for Routes with common prefix to define a new sub-router with optional middleware.
  148. //
  149. // api := app.Group("/api")
  150. // api.Get("/users", handler)
  151. func (grp *Group) Group(prefix string, handlers ...Handler) Router {
  152. prefix = getGroupPath(grp.Prefix, prefix)
  153. if len(handlers) > 0 {
  154. grp.app.register(methodUse, prefix, grp, handlers...)
  155. }
  156. // Create new group
  157. newGrp := &Group{Prefix: prefix, app: grp.app, parentGroup: grp}
  158. if err := grp.app.hooks.executeOnGroupHooks(*newGrp); err != nil {
  159. panic(err)
  160. }
  161. return newGrp
  162. }
  163. // Route is used to define routes with a common prefix inside the common function.
  164. // Uses Group method to define new sub-router.
  165. func (grp *Group) Route(prefix string, fn func(router Router), name ...string) Router {
  166. // Create new group
  167. group := grp.Group(prefix)
  168. if len(name) > 0 {
  169. group.Name(name[0])
  170. }
  171. // Define routes
  172. fn(group)
  173. return group
  174. }