group.go 5.4 KB

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