-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is it possible to use router in backend implementations to generate URLs to frontend resources? #6
Comments
Funny you should mention this--there's a proposal for URL reversal in Would this satisfy your use case? As a separate aside, I'm curious how often you change the format of existing routes. The "make it easy to change" argument is quite familiar to me, but I'll admit I've never done it myself, since in my experience doing so almost always breaks existing clients. That being said, the question comes up a lot (and came up a lot for the previous version of Goji as well), and I suspect I may be missing something; any insight you have would be greatly appreciated! |
Hmm, maybe. Would it look something like this? var (
HelloRoute = pat.Get("/hello/:name")
ThreadRoute = pat.Get("/threads/:id")
)
mux.HandleFuncC(HelloRoute, hello)
u := HelloRoute.URLPath(map[pattern.Variable]string{HelloRoute.Name: "foobar"}) I can't say for sure until I try it out for real.
How often? So far, very infrequently. However, the primary reason for that is precisely because I know that there may be things broken as a result. It's hard to be sure I didn't forget to update all instances that hardcode the paths somewhere. However, in most cases I control all clients and everything is written in Go. There is an incredible tool at my disposal that can help catch things I forgot to update, that is the Go compiler and its static type system. I'd like to start using it for this task, and doing that will enable me to change routes effortlessly - if or when I have that need. |
It'll probably look closer to u := HelloRoute.URLPath(map[pattern.Variable]string{"name": "foobar"}) (I don't know how to make something like And understood RE: the desire for safety / leaning on the type system for correctness. |
Gotcha. I'll think about what can be done about pattern variables, because using "name" string means the Go compiler will not give me an error if I were to change the name of that variable and forget to update it somewhere. That defeats a part of the goal. I know it's not an easy problem to solve, but I'm interested in thinking more about it. I can also point you to a recent real-world example of where I ran into this, which can help explain my motivation. When working on a tracker app, in one of the WIP commits I had this hardcoded URL path with the comment // TODO: Use router(s).
path := fmt.Sprintf("/%s/.tracker/%d", repo.URI, id)
fragment := fmt.Sprintf("comment-%d", commentID) The entire value of // Use Sourcegraph app router for repo app path and Tracker app router for the rest.
trackerURL, err := sgrouter.Rel.Get(sgrouter.RepoAppFrame).URLPath(
"Repo", repo.URI,
"App", s.appName,
"AppPath", "",
)
if err != nil {
return fmt.Errorf("failed to produce relative URL for tracker app: %v", err)
}
issueURL, err := trackerrouter.Router.Get(trackerrouter.Issue).URLPath("id", formatUint64(issueID))
if err != nil {
return fmt.Errorf("failed to produce relative URL for issue: %v", err)
}
u := &url.URL{
Path: path.Join(trackerURL.Path, issueURL.Path),
Fragment: fragment,
}
htmlURL := template.URL(conf.AppURL(s.appCtx).ResolveReference(u).String()) At some point I tried to comment out Also note that the value of Hopefully this real-world example can be helpful in showing my motivation. |
Hi,
I have a question about this package. I've looked through the README and godoc.org (for the original version) and couldn't find a conclusive answer.
Suppose I have a web project that separates the frontend code (including display stuff, html, css, and http request routing and handling) from the backend service implementation (expressed as a Go interface, implemented by some concrete type).
In some situations I'd like to be able to generate URLs to frontend resources from the backend.
Is it possible to reuse the router for that purpose? For example, suppose I want to generate a relative URL to the "hello" resource named "foobar".
Can I do that in some way using the router? For example, maybe:
Is this supported right now, and if not, is it support planned? Or do you see a better way to resolve the scenario I described above.
My goal is to avoid duplicating the routing logic in the frontend and backend, so that changing the hello route from
/hello/:name
to/hi/:name
should only have to be done in one place, and it'd affect both frontend and backend.Thanks! I like the other decisions made by this library, like keeping it simple, using
context.Context
, etc.The text was updated successfully, but these errors were encountered: