Giter Club home page Giter Club logo

Comments (7)

shenqidebaozi avatar shenqidebaozi commented on July 18, 2024

Yes, adaptation to stream middleware is rudimentary because the current interface model does not have a good abstraction

from kratos.

wscalf avatar wscalf commented on July 18, 2024

Would there be interest in proposals around this? We haven't looked super closely at it, but it seems like there would be a few options:

  • Could approach it the way gRPC does with separate interfaces and implementations for unary and streaming endpoints. This is what we've done for now- reimplementing the middleware we need as gRPC stream interceptors and injecting them: https://github.com/project-kessel/relations-api/pull/105/files#diff-85d6db9d4d33f7064a02bbe45907ffdaca1cd1382bbfdb5ab8c4a7e77841cea5R25
  • Or, if there's a desire to unify unary and streaming middleware under one interface, that should be possible if the interface is streaming-first, since a unary request could be thought of as a streaming request with one incoming and one outgoing messages. I could work up something more concrete around this if there's interest.

from kratos.

shenqidebaozi avatar shenqidebaozi commented on July 18, 2024

@wscalf OK

from kratos.

shenqidebaozi avatar shenqidebaozi commented on July 18, 2024

But we need to think about how to do it better

from kratos.

wscalf avatar wscalf commented on July 18, 2024

FWIW, I did some poking around at what it would take to have a unified middleware interface for unary and streaming endpoints. It does look possible, and there's some precedent for doing so: go-grpc-middleware defines a Reportable interface and interceptor wrappers that allows for the same implementations to be used with both kinds of endpoints. It's only used for logging, though it seems like something similar could apply generally.

I think it would be a breaking change to the middleware interface to be able to observe and react to multiple incoming or outgoing messages, but existing middleware could still be called from the UnaryServerInterceptor and accessed by the HTTP transport as they are today, alongside the unified middleware, so a piece-by-piece migration should be possible without breaking current functionality or end-user authored middleware.

Maybe something like: type Handler func(ctx context.Context, receiveMsg, sendMsg func(msg any) error, info CallInfo) error, which would allow implementations to keep more or less the natural flow they have now while being compatible with streaming.

This would allow for implementations like:

func Validator() middleware.Middleware {
	return func(handler middleware.Handler) middleware.Handler {
		return func(ctx context.Context, receiveMsg, sendMsg func(msg any) error, info CallInfo) error {
			recv := func (req any) error {
				if v, ok := req.(validator); ok {
					if err := v.Validate(); err != nil {
						return errors.BadRequest("VALIDATOR", err.Error()).WithCause(err)
					}
				}
				return nil
			}
			
			return handler(ctx, recv, func(any) error {return nil}, info)
		}
	}
}

Or if a middleware wanted the flexibility to treat streaming endpoints differently (ex: if logging middleware didn't want to log streamed inputs), that would still be possible by observing properties on CallInfo (which atm is intended to indicate whether the requests and/or responses are streaming, which would be a passthrough of grpc.StreamServerInfo for streaming gRPC requests and false/false for unary and HTTP requests.)

Thoughts/feedback? I've been mostly exploring so far but could put a draft PR together to provide something more concrete if there's interest, or pivot if this seems totally off the mark.

from kratos.

akoserwal avatar akoserwal commented on July 18, 2024

@go-kratos/contributor
@shenqidebaozi

from kratos.

shenqidebaozi avatar shenqidebaozi commented on July 18, 2024

I've been quite busy lately, let me take a look now

from kratos.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.