Go router with preg_match - go

I'm trying to rewrite a router on Go that will call for specific functions if request_uri matches the pattern.
It should accept following routes:
|^/v2/Command/create$|
|^/([^/]+)/postCommands$|
|^/v2/user/sessions/(.+)/.+|
There are some others and it should be scalable, so the new route can be simply added to a map
Right now it is done on PHP via preg_match($pattern, $_SERVER['REQUEST_URI'], $params)
Is there a method to do a smiliar thing on Go?

https://github.com/gorilla/mux should help you much at this.
r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler)
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
vars := mux.Vars(request)
category := vars["category"]

Related

Can't we include vars in gorilla subrouter pathprefix?

I'm trying to add a subrouter to my router code :
router := mux.NewRouter()
baseRouter := router.PathPrefix("/api/v1").Subrouter()
managementRouter := baseRouter.PathPrefix("/managing/{id}").Subrouter()
managementRouter.Use(auth.ManagingMiddleware)
managementRouter.HandleFunc("/add-employees", management.AddEmployeesToOrganization).Methods("POST")
The goal is to force the client to give an id variable on each call to managementRouter
functions.
Although, when i send a request like this :
/api/v1/managing/627e6f7e05db3552970e1164/add-employees
... I get a 404. Am I missing something or is it just not possible ?
Ok so I found a solution in my dream last night haha
Basically the problem with the following prefix :
managementRouter := baseRouter.PathPrefix("/managing/{id}").Subrouter()
Is that the router has no way of knowing where the id field stops. So when we access an endpoint with for example this url : /api/v1/managing/627e6f7e05db3552970e1164/add-employees, the router believes that the {id} variable is literally 627e6f7e05db3552970e1164/add-employees and doesn't match any route after it.
So the solution I found is to tell the router what comes after the variable. For that, you just add a slash after the variable :
managementRouter := baseRouter.PathPrefix("/managing/{id}/").Subrouter()

Programmatically set an url parameter in gin context for testing purpose

I am writing some test suites for gin middlewares. I found a solution to test them without having to run a full router engine, by creating a gin context like this :
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
The goal is to test my function by calling :
MyMiddleware(c)
// Then I use c.MustGet() to check if every expected parameter has been transmitted to gin
// context, with correct values.
One of my middlewares relies on c.Param(). Is it possible to programatically set an Url param in gin (something like c.SetParam(key, value)) before calling the middleware ? This is only for test purpose so I don't mind non-optimized solutions.
Finally figured it out by using IntelliJ to inspect the structure, I can just set it the raw way :
c.Params = []gin.Param{
{
Key: "id",
Value: "first document",
},
}
I was not able to get the accepted answer to work due to the c.Request.URL being nil in some of my tests.
Instead, you can set the query like this:
c.Request.URL, _ = url.Parse("?id=mock")

Kubernetes go client: list events

I am trying to get a list of events in the namespace, but with or without FieldSelector I get an empty list. Is this the right way to do it?
eventListOptions := metav1.ListOptions{FieldSelector: fields.OneTermEqualSelector("involvedObject.name", job.Name).String()}
jobEvents, _ := clientset.EventsV1beta1().Events(GetNamespace()).List(eventListOptions)
If you print error return by List, you should get error something like "involvedObject.name" is not a known field selector: only "metadata.name", "metadata.namespace"
use CoreV1 instead of EventsV1beta1
The line will be something like below:
jobEvents, _ := clientset.CoreV1().Events(GetNamespace()).List(eventListOptions)
"involvedObject.name", job.Name isn't supported by EventsV1beta1
Hope it'll help.

Handle array of ids in a request using gorilla/mux

I need to handle such a request using gorilla/mux:
/objects?id=JDYsh939&id=OYBpo726
As I understood while reading the documentation, I can specify a pattern like this: {name:pattern} but I don't know if it's would work to specify that the url will contain several times the id parameter.
Any ideas?
You do not need to specify the parameter for that as the query string parameters go into the corresponding collection of the HttpRequest.
The following code shows how to handle them:
r.HandleFunc("/objects", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello! Parameters: %v", r.URL.Query())
})
See https://golang.org/pkg/net/url/#pkg-examples on how to deal with URL query string parameters.

GoREST endpoint path

I'm writting a web service with Go and I'd like to have url like :
http://example.com/WEB/service.wfs?param1=2&param2=test.....
I'm using GoREST and my Endpoint url is :
method:"GET" path:"/WEB/service.wfs?{param:string}" output:"string"
My problem is that it never return the "param" but it does if I use the endpoint :
method:"GET" path:"/WEB/service.wfs/{param:string}" output:"string"
Is there a way to handle the "?" ?
You can do this in gorest though it's not as nice as gorest's preferred mechanism.
Don't include your query parameters in your endpoint definition
method:"GET" path:"/WEB/service.wfs" output:"string"
Instead, you can get at the context from your registered end point and get the query parameters using something like
func (serv MyService) HelloWorld() (result string) {
r := serv.Context.Request()
u, _ := url.Parse(r.URL.String())
q := u.Query()
result = "Buono estente " + q["hi"][0]
return
}
I have had a look at the GoREST package you are using and can not see any way of doing this.
I have always used gorillatoolkit pat package.
gorillatoolkit
There is an example of what you want to do about half way down.
category := req.URL.Query().Get(":category")
This way you can get the query parameters on the request URL by the key.
Hope this helps.

Resources