Microsoft YARP
github.com
github.com
Looking at the docs around this, I'd probably start w/ Direct Forwarding so I have more control over how things route:
https://microsoft.github.io/reverse-proxy/articles/direct-fo...
I'm really curious, does Microsoft have a crew of anthropologists walking around to figure out which team is reinventing wheels?
I mean Google reinvents chat every couple of years, and that's just the ones that come out in public <_<
If I were looking for an honest solution for the first part, I might start with a standardized way of classifying technical problems and solitons. Maybe then it would be possible to build a directory of sorts for existing solutions that could be referenced when the need for a solution arises anywhere within the company.
Quite literally, yes. Microsoft research has (or at least had) anthropologists on crew.
The ease with which you can build a tailor-made reverse proxy is pretty amazing.
Additionally, YARP is cross-platform capable, so you can run the same proxy on Linux, macOS, and Windows. NGINX doesn’t even provide that, for example.
In terms of customizations, YARP is more like “what feature do you need to build in” than “how do I need to configure”. You can quickly build a simple reverse proxy and just about as easily setup a full load balancing solution, but the simple use case doesn’t need to include any of the code for the advanced use case.
nginx runs on all three of those platforms. If you mean the binary, this is surely misleading as you just move the burden from getting your platform specific binary to your platform specific .net runtime.
I can literally throw a stick and hit several devices in my office that NGINX runs on but C# does not.
Yes, when does this happen? That's what I'm trying to understand. You've provided some possible feature benefits to a DIY solution but you're really just trading NGINX internals for YARP internals here. At first glance, to my eye, one of those is going to have better community support and documentation.
> Additionally, YARP is cross-platform capable, so you can run the same proxy on Linux, macOS, and Windows. NGINX doesn’t even provide that, for example.
Yes it does? You might need to elaborate because this is just incorrect but I suspect you're trying to make a different point.
> In terms of customizations, YARP is more like “what feature do you need to build in” than “how do I need to configure”. You can quickly build a simple reverse proxy and just about as easily setup a full load balancing solution, but the simple use case doesn’t need to include any of the code for the advanced use case.
My main issue with this idea is that the average consumer of this is going to be better positioned to handle the engineering hurdles of writing their own advanced use cases.
So you are right, it is a very specialized situation, but the key stakeholders who asked, contributed and collaborated with the .NET group are exactly these engineers who previously did a DIY solution.
This is an interesting take that I think is perhaps naive. Microsoft has a vested interest in pushing .NET as a development platform and can push teams to use the company's flagship programming stack in everything it does. From the perspective of given individual teams within the company this may not appear to be self-motivated but how could it not be, given the driving requirements to use MS-approved technology stacks?
What your comment misses the mark on is what the driving force behind those engineering decisions is. If the decision is driven by corporate guidance to use .NET or else (this is a hypothetical), it's not exactly because the engineers themselves wanted to write something from scratch in .NET to solve a particular well-solved problem.
Office for example took React Native as a UI toolkit and invested in that instead of .NET. Typescript was invented to help them. The Windows division uses C++ based COM / WinRT and built a independent framework.
Microsoft is not a pure .NET shop. There are not even a anti-Java shop
While this is no doubt true the implied context of my reply was to the idea that Microsoft's engineers were selecting the best available option, the terms of "best" insinuating "best for anyone" rather than "best for software developer at Microsoft" -- a key difference.
> Office for example took React Native as a UI toolkit and invested in that instead of .NET.
Only after many years of trying to make WPF work and seeing the tide go another way.
> Microsoft is not a pure .NET shop. There are not even a anti-Java shop
For sure, C# and J# were basically the replacements for the failed attempted co-opting of Java that was J++. As far as I can tell their only Java related product is their own build of OpenJDK designed to be used on Azure. It's unclear what contributions they've really made in the space.
While they may not be a "pure .NET shop", I'd bet they're the closest thing out there.
I'm not suggesting Microsoft 100% ignores broader trends but this is sort of an aside from the crux of the original commentary.
As Ballmer used to say: “developers, developers, developers”. Microsoft has long known that what is best for developers is what is best for Microsoft.
In highly regulated or extremely sensitive industries.
The first specific example I can think of is JupyterHub - it handles user management and starting/stopping Jupyter Notebook servers, then provides a reverse proxy for users to access their notebook servers directly.
Basically, we needed to to auth on each request (can the user see this per a slightly complicated rights system) and we routed to automatically spin up containers,so discovery was also custom
Perhaps a bit of a stretch. I am currently choose golang for a more systems like project because of startup time and gc pauses in c#/dotnet. Definitely nice to see nativeaot which should address the startup time issues.
Microsoft made a huge organizational change to support their cross-platform initiatives.
In 2022 everything is a system programming language. Next on that list is Javascript, I am sure.
Yes but cool people will write their systems software in Typescript. :)
It won't become a systems language until it will let you to directly access hardware and do memory management, it will have improved performance and it will be natively AOT compiled.
https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
What is the purpose of a reverse proxy?
Reading online: security, load balancing, https seems to be mentioned.
It appears a bit to me that a reverse proxy is not doing what a web server used to do back in the days of IIS/Apache.
I see a lot of programs meant to operate on the web that use very simple http servers.
Common reasons for such a split:
1. Composing several different services into a single internet domain
2. Putting stateless or CPU-heavy workloads onto different infrastructure from long-lived, IO-intensive tasks
3. Variation of the above, allow for multiple server processes in server environments which can't scale up to single multi-threaded processes well (CRuby/CPython)
4. Split security concerns off onto a box which has a much smaller attack surface, such as a box meant to be deployed in a DMZ (examples would be HTTPS termination, authentication and authorization policy enforcement)
5. Caching of responses (this is Varnish's claim to fame)
6. Variation of the above, some CDNs work by hitting an otherwise private server for data, then replicating throughout the network for locality to end-users.
7. Application-specific behavior patching, such as adding new API endpoints or changing the behavior of existing ones
In many of these cases, people use something like NGINX, Apache or a commercial solution like an F5. In other cases (such as application-specific business logic) people will write their own code, perhaps in the future using this Microsoft project as a starting point.
8) avoid cross-origin problems and prevent unnecessary OPTIONS preflights that result in uneeded roundtrips by bundling mutiple FEs+BEs into a single origin with different paths (as opposed to mutliple domains/origins).
https://microsoft.github.io/reverse-proxy/articles/getting-s...
From my understanding Kestrel passes request to this.
> The proxy server is implemented a plugin component for ASP.NET Core applications. ASP.NET Core servers like Kestrel provide the front end for the proxy by listening for http requests and then passing them to the proxy for paths that the proxy has registered.
Imho: no in-procees reverse proxying. That should not make sense.
Ultimately we got a solid product with a not-too-dissimilar API and I have one less thing to maintain :)
Cute.
In similar cases of implementing reverse proxies in C, C++, Rust, Go and Java, there were generally benefits in various shapes and sizes like different security models, performance vs. capability trade-offs and integrated vs. specialised solutions. In this case, it just seems to be a "we don't want the stuff we didn't build ourselves" which is a shame considering the benefits of pooling resources on existing implementations would have.
It sometimes feels to me, like a huge percentage of developers reinvent the wheel
I think most devs are definitely reinventing the wheel for the ten thousandth time
There is already a solution that lets us not reinvent this particular wheel. It's called Excel.
I hate using it.
I had this exact experience: “why should I reinvent the wheel?” Oh this solution doesn’t let you apply partial payments or apply one payment to multiple invoices. This one doesn’t create account statements. This one can’t fax invoices. This one only supports Stripe (and has its own undocumented billing API because who would use anything other than Stripe?). This one has a weird XML definition system for subscription pricing which makes it difficult if not impossible to handle negotiated rates on a per-account basis. Not to mention having to teach billing people how to write the weird XML. This one won’t prorate invoices. This one is a cloud service that costs $100+ a month and is liable to be unavailable when I really need it! They all have weird features that I will never use.
Ok, we’ll go with this imperfect one and make some changes. But where’s the entry point? How does weird framework in weird language even work? What are the conventions? How is the original developer differing from those conventions?
And then you come to the realization that the wheel gets reinvented because the existing wheels were made with specific business logic in mind. While this can often be generalized for a particular industry or set of use cases, it often does not and can not cover all use cases. The wheel is reinvented.
(Not so fast with the XKCD comic about new standards. We’re not imposing standards on others, we just need our software to work for us.)
Sometimes the wheel doesn’t need to be reinvented. Some help desk software I wanted to use needed some slight tweaks. The entry points were obvious and the development environment was easy to setup. I made the tweaks and was good to go.
> is a shame considering the benefits of pooling resources on existing implementations would have.
What exactly would you prefer these developers spend their time on instead of this work?
There are a lot of benefits to being able to integrate your own reverse proxy directly into your software stack. C# developers enjoy these as much as anyone else would.
I take this at face value but it would be nice to know what the benefits are vs nginx and other off the shelf solutions.
The readme explains the benefit for Microsoft but not how it stacks against off the self solutions.
Totally agree. Seems to me that the main benefit is that it's easy to extend in .NET, vs. C/C++/Lua/WASM.
Biggest difference in my view is being able to make synchronous blocking calls directly into any arbitrary business code in order to determine the fate of a request. This can include rule/policy engines as well as auditing & tracing frameworks.
Also it's embeddable and self-hostable into any .NET / AspNet Core application.
I have no insight into it but my gut tells me windows server exclusive shops are probably dwindling and have long ago realized they needed to start moving to Linux, especially now that .NET is officially supported there. I think the days of reinventing everything in C#/.NET/windows are coming to an end fast.
So reinventing "everything" in a Windows Server environment is slowly coming to an end, with Windows server becoming a hypervisor for VMs/containers and a runtime for .NET/CLR.
The economics of getting all of the FOSS infrastructure tooling in a "Windows native" form is being beaten by just running them in containers/VMs on whatever hypervisor is available.
In the same way, Linux is becoming a hypervisor for containers and the various container runtimes.
1. There are already good reverse proxy libraries in C#?
2. There are already good reverse proxy libraries in other languages?
3. There are already good reverse proxy applications?
If it's #1, then yeah, it would be nice if the ReadMe explained why YARP is different. To be fair, they're at least consolidating a bunch of efforts within Microsoft:
> We found a bunch of internal teams at Microsoft who were either building a reverse proxy for their service or had been asking about APIs and tech for building one, so we decided to get them all together to work on a common solution, this project.
If it's #2, then what do C# developers do? Having to build your proxy in another language isn't a deal-breaker, but there are advantages to keeping your project/team/company on a single language.
(And Microsoft does contribute to Envoy [1][2].)
If it's #3, that only works up to a point. My old team used Nginx, which was perfect in the beginning. But over time we needed to customize things in ways that were difficult to do within Nginx's architecture (either in Lua or in C), leading to hackier and hackier solutions. Using a proxy library to build exactly what you need can make things much simpler.
[1] https://blog.envoyproxy.io/general-availability-of-envoy-on-...
[2] https://techcrunch.com/2020/08/05/microsoft-launches-open-se...
This is the central argument for me regarding why we don't "just use nginx". We actually do use it for some corporate websites, but not for our main product.
There is a ton of power hiding here... With a well-supported first-party RP framework, how long would it take for a determined developer to replicate the most important bits of the nginx feature set? Imagine being able to throw a blazor dashboard on top of this stuff. Wiring up real-time events/metrics would be super trivial if you are even remotely interested in learning how the DI system operates. Mix in a little bit of SQLite and you could have something I may argue provides a better UX than what nginx offers today.
- Logging the exact metrics we wanted to our metrics service. (We wrote a bunch of Lua code to do this.)
- Loading the set of backend services from Zookeeper. (We had a sidecar process that would periodically sync from Zookeeper to a config file, then call `nginx reload`.)
- Routing requests to different datacenters based on where the user's data was homed. (We had Go libraries to do this, and it would have been nice to be able to just call into that. I think we ended up putting this functionality in the sidecar.)
- Changing the way we streamed a response based on an HTTP header from the application. (We ended up writing a C module for this.)
- Changing the backend selection algorithm from "least connections" to "best of 3 random choices". Nginx added support for this in 2018, apparently.
There were ton of things we solved with Lua, which wasn't ideal. Since that's the only Lua in our codebase, everyone who touches it has to make a mental switch to remember all the weird edge cases (as you do with any language), plus 1-based array indexes, plus no static types.
Plus, any Lua or C you write has be contorted to fit Nginx's multi-stage request/response architecture. If you're writing a plugin that is meant to play nice with other plugins, then the contortions may be worth it. But for us, a proxy library would have given us the freedom to write code that was simpler and easier to understand.
The team moved to Envoy after I left: https://dropbox.tech/infrastructure/how-we-migrated-dropbox-...
Yup. Eventually a configuration language becomes a shitty programming language, so why don't we just use a programming language?
http://mikehadlow.blogspot.com/2012/05/configuration-complex...
By your logic, the world should be operating on a single OS, with a single web browser, paired with a single web server, because why re-implement something that already exists?
I think pretty much every open source project that wants to be taken seriously needs to compare itself with its competitors.
Similarly, Igor built nginx to solve a particular problem, and I think it was a few years before it went open-source.
I can't imagine most OSS developers have delusions of grandeur.
I expect some of the comments under this post to age very badly.
I've spent the last 4 years at Fly.io wishing for a nice, full featured, proxy framework. This looks pretty darn good to me.
(At any rate, they employ Chris McCord, the creator of Phoenix, and have spent considerable resources pushing Phoenix. So it's clear that they aren't beholden to any one language or ecosystem.)
For better or worse we're not really fixated on one language.
"YARP is a reverse proxy toolkit for building fast proxy servers in .NET using the infrastructure from ASP.NET and .NET."
And WASM is already supported, app size about 1MB including runtime and GC
That line could easily have read “for building fast proxy servers in the JVM” or “for building fast proxy servers in node.js” or whatever else, and it would’ve still been just as restrictive.
that's why languages like GO makes more sense for that kind of use cases
microsoft not wanting to support CoreRT back in the days was their biggest mistake ever, shame on the people at microsoft who lobbied against it, shame!
I have been using it with reflection fully disabled in a console app and it produces a 5Mb native binary.
thanks for letting me know about that
EDIT: found it: https://github.com/dotnet/runtime/issues/61231
And sizes will be going quite a bit lower with NativeAOT this year.
I can't help but be wary of anything Microsoft announces that's open source. Without engaging in MS-bashing, I always wonder what their motivation is. Then again, part of me wants to believe there's good, avid coders working there.
MS is one of the largest open source contributors these days. .Net is open source and cross-platform. They even have an open source Linux distribution. They actively contribute to Rust, webAssembly, the Linux kernel, and Kubernetes.
[1] https://news.ycombinator.com/item?id=28975856