github.com/gofiber/fiber/v2@v2.47.0/group.go (about)

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