-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Echo v5 #1302
Comments
I'd like to know if we can make #1214 in v5. |
Consider using only one log module |
Which one? |
StdLogger looks fine to me provided we have "bring your own logger" option is given. |
I like it Context as interface, but need improve now code. add methods: (e *Echo) SetNewContext(newCtx func() Context) {
e.pool.New = func() interface{} {
return newCtx()
}
}
func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := e.pool.Get().(Context)
c.Reset(r, w)
......
c.Free()
e.pool.Put(c)
} my client code: type MyContext strcut {
echo.Context
MyField1 xxx
MyField2 xxx
MyField3 xxx
.... xxx
}
func (ctx *MyContext) Free() {
ctx.MyField1 = nil
ctx.MyField2 = nil
ctx.MyField3 = nil
....
}
func toEchoFunc(h func(ctx *MyContext) error) echo.HandlerFunc {
return func(ctx echo.Context) error {
return h(ctx.(*MyContext))
}
}
echo.SetNew(func() echo.Context {
return &MyContext{Context: echo.NewContext()}
})
echo.GET("/xxx", toEchoFunc(func(ctx *MyContext) error {
xxxxxxx
})) |
add gin.IRoutes(iris.Party) interface. e := echo.New()
initHandlers(e) // now is error
initHandlers(e.Group("/"))
...
func initHandlers(g *echo.Group) {
g.Get("/x", a)
g.Get("/y", a)
} |
How about #1261 ? |
I think that |
Can we have an examples section describing the existing APIs from https://godoc.org/gopkg.in/labstack/echo.v4 or going forward https://godoc.org/gopkg.in/labstack/echo.v5? They can be hosted from https://echo.labstack.com/ |
|
@aimeelaplant I don't llke that echo.Context should implement context.Context. |
Remove logger interface{} or simple it! |
A way to define routing from a config file? Can already print out routing config to JSON, so hopefully the opposite can be achieved! (Though hopefully something simpler than JSON) A nice config schema could be the one Play Framework uses |
|
How about make the router more generic so that we can use it with many other protocols (such as gRPC, etc.), not just HTTP? |
Hi everyone! I'm from Node.js's world and I've been looking at echo only a couple days. I've been using koa2 (the successor of express) for 2 years so I will be comparing them. 1. There is no any router in the boxKoa is just a middleware pipeline. You are free to use your favorite router or write your own from scratch. But there is a trick -- composition. a) you can create three apps and mount one to anotherconst mount = require('koa-mount')
const Koa = require('koa')
const a = new Koa()
a.use(async function (ctx, next) {
ctx.body = 'Hello'
})
const b = new Koa();
b.use(async function (ctx, next) {
ctx.body = 'World'
})
// app (root)
const app = new Koa()
app.use(mount('/hello', a))
app.use(mount('/world', b))
app.listen(3000)
console.log('listening on port 3000')
https://github.com/koajs/mount#mounting-applications b) you can mount middleware as isconst mount = require('koa-mount')
const Koa = require('koa')
async function hello(ctx, next) {
ctx.body = 'Hello'
}
async function world(ctx, next) {
ctx.body = 'World'
}
const app = new Koa()
app.use(mount('/hello', hello))
app.use(mount('/world', world))
app.listen(3000)
console.log('listening on port 3000') https://github.com/koajs/mount#mounting-middleware c) you can create a router and mount it as middlewareconst Koa = require('koa')
const Router = require('koa-trie-router')
const app = new Koa()
const router = new Router()
router
.use(function(ctx, next) {
console.log('* requests')
return next()
})
.get(function(ctx, next) {
console.log('GET requests')
return next()
})
.put('/foo', function (ctx) {
ctx.body = 'PUT /foo requests'
})
.post('/bar', function (ctx) {
ctx.body = 'POST /bar requests'
})
app.use(router.middleware()) // or app.use(mount('/foo', router.middleware()))
app.listen(3000) https://github.com/koajs/trie-router#usage As opposite, Express has the built-in router. Why did the developers exclude it from the web-framework? Well, you can try to google the answer :) 2. Extremely simple middleware usageLet's say I have three middleware. If I want to execute next middleware I just do const Koa = require('koa')
const app = new Koa()
app.use(async function (ctx, next) {
console.log('middleware 1')
return next() // go further
})
app.use(async function (ctx, next) {
console.log('middleware 2')
return // stop here
})
app.use(async function (ctx, next) {
// this middleware will have never called
console.log('middleware 3')
ctx.body = 'Hello World'
})
app.listen(3000) This code prints to stdout
Echo brings me several kinds of middleware. One when I want to pass through app.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
fmt.Println("test 1")
return next(c)
}
}) and another in other case app.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
}) But as a developer I actually want something simple, something like this: app.Use(func(ctx echo.Context, next echo.HandlerFunc) {
fmt.Println("test 1")
return next(ctx)
}) 3. Wrapping of Request and Response is not a bad ideaThis approach allows us to decompose Request \ Response helpers from Context object: app.use(async function (ctx) {
ctx // is the Koa Context
ctx.request // is a Koa Request
ctx.response // is a Koa Response
ctx.req // Node's request object
ctx.res // Node's response object
}) 4. ctx.assert(exp, [status], [msg]) as the declarative approach for throwing errorsIt is quite often when we check some business rules and throw errors. Pseudo code could look as follows:
We prefer do it as singe line via ctx.assert(x == 2, 400, /* [Custom message] */) https://koajs.com/#ctx-assert-value-status-msg-properties- P.S.: I don't know it will be helpful for you or not. Anyway thank you for your amazing work 👍 "There is no limit of perfection" :) |
First of all, thanks for echo. It is my absolute favorite. So I personally think it would be nice if you could only use the router (without echos I know it's possible to do current ones, but it would be nice if these parts were better separated. |
#1362 use http.FileSystem interface and support 3rd party implementation |
No or few breaking changes instead of barely needed or easily self-implemented features. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Per #1017 I would like to reiterate this comment by @ghostsquad: If this is going to be done, I would strongly recommend not using the built-in go logger methods as a base for the interface. There are many examples out there that talk about the anti-pattern of using log methods as control flow, as is such with
The basis of this interface is derived from the post made by Dave Cheney: https://dave.cheney.net/2015/11/05/lets-talk-about-logging type InfoLogger interface {
// Info logs a non-error message with the given key/value pairs as context.
//
// The msg argument should be used to add some constant description to
// the log line. The key/value pairs can then be used to add additional
// variable information. The key/value pairs should alternate string
// keys and arbitrary values.
Info(msg string, keysAndValues ...interface{})
// Enabled tests whether this InfoLogger is enabled. For example,
// commandline flags might be used to set the logging verbosity and disable
// some info logs.
Enabled() bool
}
// Logger represents the ability to log messages, both errors and not.
type Logger interface {
// All Loggers implement InfoLogger. Calling InfoLogger methods directly on
// a Logger value is equivalent to calling them on a V(0) InfoLogger. For
// example, logger.Info() produces the same result as logger.V(0).Info.
InfoLogger
// Error logs an error, with the given message and key/value pairs as context.
// It functions similarly to calling Info with the "error" named value, but may
// have unique behavior, and should be preferred for logging errors (see the
// package documentations for more information).
//
// The msg field should be used to add context to any underlying error,
// while the err field should be used to attach the actual error that
// triggered this log line, if present.
Error(err error, msg string, keysAndValues ...interface{})
// V returns an InfoLogger value for a specific verbosity level. A higher
// verbosity level means a log message is less important. It's illegal to
// pass a log level less than zero.
V(level int) InfoLogger
// WithValues adds some key-value pairs of context to a logger.
// See Info for documentation on how key/value pairs work.
WithValues(keysAndValues ...interface{}) Logger
// WithName adds a new element to the logger's name.
// Successive calls with WithName continue to append
// suffixes to the logger's name. It's strongly reccomended
// that name segments contain only letters, digits, and hyphens
// (see the package documentation for more information).
WithName(name string) Logger
} or even simpler, is in type Logger interface {
Log(keyvals ...interface{}) error
} With some additional methods available from the library such as |
Dependency injection please |
Thanks for Echo 👍 IMHO, Echo v5 need to upgrade JSON Marshal/Unmarshal speed. For example, we can use json-iterator/go for replace standard Here is benchmark: And it's easy to replace, because Replace import "encoding/json"
json.Marshal(&data) with import "github.com/json-iterator/go"
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(&data) And replace import "encoding/json"
json.Unmarshal(input, &data) with import "github.com/json-iterator/go"
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Unmarshal(input, &data) |
No, this is a known incorrectness. |
But Gin use it via build flag |
What about reducing logger interface? The current interface makes it cumbersome to implement a logger. |
IPv6 support please. #826 |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Please reopen. |
Do you have a development plan |
What is going on? |
GitHub issue bots are the worst thing that could happen to open-source community. Especially the @stale bot. |
Yes, the stale bot is a little nasty sometimes, but also helpful in some situations. But this discussion is about ideas and suggestions for v5. We labeled some issues and PRs already for the next major release and will start with actual development soon (after resolving open bind and router issues in v4). Some suggestions with no issues or PRs yet will be openend for a more detailed discussion and first PRs merged. Anyone who wants it to move faster or wants some ideas to be realized is very welcome to contribute. |
Reopening this one and pinning on the top. If p.s. most popular thing - logger will be trimmed down to bare minimum as in handlers developer is free to choose what ever he/she chooses to use as the logger instance. also there are few Echo internal places where things are logged and having huge interface for that purpose is unnecessary. p.s.s. some of the things @vishr mentioned in first post and some other things are already introduced in |
Everyone interested, I'll close this issue. Please use #2000 for discussion of |
Anyone who is interested what is planned in This is announcement and proposed timeline for |
Let me know what you want to see in v5 ✌️
Here are my thoughts?
I don't likeContext
as an interface, we did it to expand on it using a custom context; however, casting it back in handler is tediousJWTErrorHandler
(How about adding next to the handler so you can rely on next auth handler)The text was updated successfully, but these errors were encountered: