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