The impact on middleware of expanding APIs with Go's interface smuggling

栏目: IT技术 · 发布时间: 4年前

内容简介:Recently, the Go blog hadThis is a quite popular approach, one used by many packages in Go's standard library and third party packages. However, it has a dark side, and that is its unfortunate effects on middleware.The problem for middleware is best illust

Recently, the Go blog had Keeping your Modules Compatible which is about doing exactly that as you add features and want to expand your module's API. When the module's API involves interfaces, one of the approaches they suggested is what I've calledinterface smuggling and what other people have called interface upgrades . Let me quote the article:

When you run into a case where you want to add a method to an existing interface, you may be able to follow this strategy. Start by creating a new interface with your new method, or identify an existing interface with the new method. Next, identify the relevant functions that need to support it, type check for the second interface, and add code that uses it.

This is a quite popular approach, one used by many packages in Go's standard library and third party packages. However, it has a dark side, and that is its unfortunate effects on middleware.

The problem for middleware is best illustrated by the most common sort of middleware, which is things that interpose in the chain of HTTP handlers to modify the results. Much middleware wants to look at or act on some aspect of the HTTP reply, for example to gather metrics based on the result code , which means that it must modify and proxy the http.ResponseWriter passed to child http.Handler s. Over time the http package has acquired a whole collection of smuggled interfaces on ResponseWriters, such as http.CloseNotifier (which is deprecated), http.Flusher , http.Hijacker , and http.Pusher . In the future there will probably be more.

(In addition, the ResponseWriter may or may not support io.ReaderFrom .)

If you're a piece of middleware, the ResponseWriter you're passed may support some, many, or all of these additional APIs. However, Go provides you no good way to pass this support through your proxy ResponseWriter that you're going to pass to children Handlers. The Prometheus people try hard to do it anyway, and the result is rather messy and involves a combinatorial explosion of the possible combinations of APIs. As the case of io.ReaderFrom shows, these additional APIs don't even necessarily come from the http package . A smuggled interface from anywhere may need to be supported.

One answer to this is that you just don't support these additional APIs in your middleware, or you only support a few of them. The problem with this is that the ResponseWriter and the client code that people are trying to use your middleware with well have been developed, tested, and normally used in an environment where these expanded APIs are used, not cut off. As we all know, if you don't test it it doesn't work. Your middleware may be the first code to try to pass the next hop a ResponseWriter with a genuinely narrow API, because such narrow APIs may mostly come from middleware. And of course if there are any bugs in the result, people will blame your middleware.

None of this is insurmountable. But beyond the problems and the hassles, it means that expanding your API with interface smuggling is decidedly not transparent if people use middleware with it. And as a practical matter, some amount of the time your new API will not be usable until middleware is expanded to cope with it (if it ever is).

Another problem is that this expansion of middleware to cope with your new API can't happen until your new API itself is pervasive. Go currently provides no support for conditional building based on the version of other packages or the state of their API, so middleware can't include any use of your new API interfaces until it doesn't have to build against versions of your package that predate them.

(People can work around this for HTTP middleware because they can make files build only on specific minimum versions of Go. Your package doesn't have this magical power; it's something available only for new APIs in the Go standard library.)

Because nothing is new under the sun, this problem was noticed back in 2014's Interface Upgrades in Go , which is one of the earliest places to call this pattern an 'interface upgrade'. The article notes the proxy problem and ends with a call to use interface upgrades sparingly. This is good advice in my opinion, but is very much at odds with the idea of routinely using interface upgrades to expand your API.

( Via .)


以上所述就是小编给大家介绍的《The impact on middleware of expanding APIs with Go's interface smuggling》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

法治构图

法治构图

季卫东 / 法律出版社 / 2012-7 / 43.00元

《法治构图》作者季卫东从1980年代末开始就一直在思考和阐述上述问题的答案,并把研究的心得陆续形诸文字发表,以期有益于点点滴滴法制改革的实践。《法治构图》就是对相关的代表性论稿的梳理和总结,可以理解为从正当过程到实质价值、从法治到民主的新程序主义建构法学观点的集大成。一起来看看 《法治构图》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换