Description
I am building a multi tenant API where tenants are allowed to have a path in their base.
For example: tenant1.base = tenant-1.com/
& tenant2.base = tenant-2.com/some-api/
I was hoping there was some way to add wildcards at the start of a route but this doesn't seem to be the case.
How can I implement my requirements ?
I was thinking of maybe running some code before the route is resolved to its handlers to internally reroute the request to a diff route, but I can't seem to find how to do this or if this is even possible.
I have tried using r.HandleContext()
as such: (example code for testing)
server.Use(func(c *gin.Context) {
if (c.Request.URL.Path != "/status") {
c.Request.URL.Path = "/status"
server.HandleContext(c);
} else {
c.Next();
}
});
But this lead to 2 requests being handled and the response body being double of what it should be. Also, I do not want to start over the whole request flow, as in: the middleware that already ran should not be executed again.
My temporary ugly solution is: (this however doesn't work for me /openapi endpoint wich is served using r.StaticFile(...)
and I expect I will run into some errors with some paths possibly matching multiple routes)
func registerRoute(server *gin.Engine, r string, handler gin.HandlerFunc) {
server.GET(r, handler);
server.GET("/:any" + r, handler);
server.GET("/:any/:any" + r, handler);
...
}
Environment
- go version: 1.20
- gin version (or commit ref): 1.9.1
- operating system: MacOS 13.4.1
Comment From: BelgianNoise
I managed to get HandleContext()
to work by adding c.Abort()
. Current code:
server.Use(func(c *gin.Context) {
if (c.FullPath() == "") {
multiTenantPaths := []string{
"/status",
"/openapi",
};
for _, path := range multiTenantPaths {
match, e := regexp.MatchString(".+"+path, c.Request.URL.Path);
if (match && e == nil) {
c.Request.Header.Set("X-Original-Path", c.Request.URL.Path);
c.Request.URL.Path = path;
server.HandleContext(c);
c.Abort();
}
}
}
c.Next();
});
server.Use(func(c *gin.Context) {
originalPath := c.Request.Header.Get("X-Original-Path");
if (originalPath != "") {
c.Request.URL.Path = originalPath;
}
c.Next();
});
Seems to work okay for now. Still interested in a better solution tho.