-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Automatic Parameter Router #2586
Conversation
That is a good ideas. Could you move the params and response to the context package? I think context packgage is used for that, And also I think we already have parse params to type there |
@astaxie I can move it under context but will it be ok if I keep it as sub folders of context? Also, Can I delete Params map from ControllerComments struct? It doesn't seem to be used anywhere |
@astaxie This is now ready for review. It has an accompanying PR in bee: beego/bee#418 which also add automatic swagger generation for method parameters. What does it do?
End result:
To this:
Note how all of the boilerplate code is gone and all that is left is pure business logic |
@eyalpost This is a great feature. But I will close it as I add golint and ineffassign tool to check the code in the CI. please fix the comments and then send a new PR. Thanks |
context/param/conv.go
Outdated
"github.com/astaxie/beego/logs" | ||
) | ||
|
||
func ConvertParams(methodParams []*MethodParam, methodType reflect.Type, ctx *beecontext.Context) (result []reflect.Value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add comments
context/param/methodparams.go
Outdated
) | ||
|
||
//Keeps param information to be auto passed to controller methods | ||
type MethodParam struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
golints need start the comments with MethodParam
Can you leave this PR open? I will do the fixes and it will run the build again automatically |
@eyalpost yea, I can let it open. But it looks will not automaticlly use the latest travis config. let's try |
I can sync my branch so I will have the latest travis |
@eyalpost thanks |
@astaxie i've made the golint fixes and updates with the latest travis. build passes |
context/response/responses.go
Outdated
) | ||
|
||
// JSON renders value to the response as JSON | ||
func JSON(value interface{}, encoding ...bool) Renderer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's already have context response, why create a new package response here. That's really confuse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where there is already package response?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As context.Output already have a lot functions based on response. I think the seperate response package does not make sense here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mainly for code readability
The idea is that a controller method can be written like this:
func(c *TaskController) PutTaskById(id int64, t *Task) (*Status, error) {
if /*not found */ {
return nil, response.NotFound
} else if /* needs redirect */ {
return nil, response.Redirect("/somePath")
}
return &Status{Status: "OK"}, nil
}
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I understand the readability. But why not just use the ctx.Output
func(c *TaskController) PutTaskById(id int64, t *Task) (*Status, error) {
if /*not found */ {
return nil, c.Ctx.StatusNotFound
} else if /* needs redirect */ {
return nil, c.Ctx.Output.Redirect("/somePath")
}
return &Status{Status: "OK"}, nil
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StatusNotFound is simply a const - I don't think it should be placed on the context object.
Redirect returns a renderer. It does not changes directly the output - so I don't think it belongs on the Output object itself. also c.Ctx.Output.Redirect
feels to verbose IMO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, response.JSON can not be put on Output because Output already has JSON. and repsonse JSON again returns a renderer which eventually calls Output.JSON.
The point of renderers was that writing to output is always done after the function is finished and not within the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c.Ctx.Output.Redirect feels to verbose IMO
When I design the Ctx, we just name request as input and response as output. we need to keep consistency with the design.
Also, response.JSON can not be put on Output because Output already has JSON. and repsonse JSON again returns a renderer which eventually calls Output.JSON.
If you return the render from the JSON, I would like to rename it to JSONRenderer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I refactored the code a bit and hopefully it will look better now.
One thing I want to keep in mind: I don't want controller code to rely on c.Ctx and want it to be as "stateless" as possible. The reason is that it makes testing the controller method much easier.
No need to setup context to test the method if it simply accepts all parameters as function parameters and returns simple objects
Please review now and let me know if this is better
@astaxie I updated the code and also added documentation here: beego/beedoc#580 |
httpResponse/response.go
Outdated
@@ -0,0 +1,52 @@ | |||
package httpResponse |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also move this package to context?
I think it doesn't belong in context. It's an implementation of the Renderer interface which also a user can do within his own packages |
I don't think so. httpResponse means response. |
No it's a helper for generating responses. Just like implementing an error interface does not mean it should be in the error package |
And it's similar to all helper method on the controller (ServeJson(), GetInt() etc. ) - they handle request\response but they're not part of the context package. |
yea, they are helper functions. But they just works for response. While response should be in context package. Like the |
So move it under context, not inside context? That's ok with me. Moved |
My idea is moving the file to context package. What's your concern? |
We have quite a lot of projects using beego and almost none of our code imports context package. The fact that it will now start importing it means (for me) these helpers are not in the correct place. |
If you already use controller, context package already imported.
It still confuse for me that httpResponse have a I think maybe should be like this:
|
I mean explicitly in code. We don't have explicit import of "github.com/astaxie/beego/context"
So how do you want to call it? |
that's what I think is you don't need to import that now. and also don't need to import httpResponse. As you can just call these functions like |
But these functions require an actual Context object while the way that my responses are built is that they don't need a context. |
you can still rename current |
maybe |
or RedirectRenderer ? |
I like |
Making it a context method again loses ability to test it. I will delete this helper for now to push this forward |
Could you also move context/httpResponse/response.go to context? or remove it |
Done |
@eyalpost thanks so much on this PR. Appreciated. |
This is a POC for a feature i've been working on that I'd like to get reviewed before I complete the work (to make sure the direction is ok)
The idea is to make Comments Controller even more "magical" by translating request parameters to method parameters.
[See updated information below]
Let me know if the direction looks ok and I will complete the missing parts. Also if you think this is good, please review the changes.
Note that most changes are in new files and there should be no changes to current flows. Changes in existing files are minimal.