Blazor Community Standup | Blazor integration with Aspire
dotnet
0:01 [music]
2:31 All right.
2:32 Hello, everyone and welcome to the Blazer community stand up,
2:37 where we talk about the latest updates to .NET web development.
2:40 I'm Daniel Roth, a principal product manager at Microsoft
2:43 on the .NET team for ASP.NET Core and Blazer.
2:47 And today I have with me Javier Calvadero Nelson,
2:50 principal software engineer on the Blazer team.
2:52 Welcome back, Javier.
2:54 Hello.
2:56 This is a two-for-one, I guess, this month, Javier.
2:59 Like normally we do our Blazer community stand up on the the second
3:02 Tuesday of every month amongst our other ASP.NET Core community stand up.
3:07 So we had so much Blazer stuff, I guess,
3:08 this month that we we were going to do two of them this month.
3:11 We have this one today,
3:13 where we're talking about Blazer integration with Aspire,
3:16 and then we have our normal Blazer
3:17 community stand up also planned next week, too.
3:20 I don't know, maybe we might have some more.
3:21 I have to still plan out the rest of the the community stand ups coming up.
3:25 But it's pretty great.
3:25 So for for you Blazer fans out there,
3:27 we've got some extra Blazer content for you.
3:30 Today we'll be talking about using Blazer with Aspire.
3:34 And now it's I guess it's just Aspire, right?
3:37 Like it used to be .NET Aspire,
3:39 but I think Aspire is, you know, stretching its wings.
3:42 It's going even beyond .NET scenarios and supporting polyglot scenarios,
3:45 which is pretty interesting.
3:46 Like so if you're if you have any,
3:48 you know, Python developer friends or Java developer friends,
3:51 like make sure you tell them about Aspire as well,
3:54 because it is now for for everyone,
3:56 for all developers, not just .NET developers.
3:59 But of course, we want to make sure Aspire is is great for .NET,
4:03 great for Blazer users.
4:04 So today we're going to talk about some of the you know,
4:07 feedback and pain points that we have heard
4:09 about when trying to use Blazer with Aspire,
4:13 and the things that we're working on to to to try
4:15 and address that and make those experiences better.
4:18 Sound good?
4:19 Before we do that, I just want to show something real quick.
4:22 Quick announcement for folks on that are with us today.
4:27 This might hopefully this only applies to people that are you know,
4:32 maybe you've you've been working with ASP.NET Core for a good
4:34 long time and you have some older apps kicking around.
4:38 Want to give you a heads up that there's an old version of ASP.NET Core,
4:42 ASP.NET Core 2.3, 2.3.
4:45 Javier, you probably you and I you and I still remember 2.3.
4:48 Like we were around Yes.
4:49 back in those early days.
4:50 But this was the version that all.
4:54 [laughter] The last version of ASP.NET Core that we supported
4:56 that it actually supported both .NET Framework and .NET Core.
5:01 So you could run it on the the the old runtime or on the new runtime.
5:05 And for a long time we've said that, you know,
5:07 we're just going to keep supporting this old version of ASP.NET Core
5:10 just on .NET Framework for folks that are trying to to migrate, right?
5:14 Like they want to you know, move from .NET Framework on old ASP.NET,
5:17 they could use this as a way to start
5:19 using ASP.NET Core in their existing .NET Framework app,
5:22 and then try to use that as a a stepping
5:24 stone in order to get to to to .NET Core,
5:27 to the modern .NET platform, .NET 10, which is the latest .NET LTS version.
5:31 We've supported this for a good long time.
5:33 At this point, you know, honestly the distance between ASP.NET Core 2.3
5:37 and ASP.NET Core and .NET 10 is so big that I think the utility of doing this is
5:42 kind of diminished over time, shall shall we say.
5:47 I don't think I would honestly recommend to anyone
5:50 moving to ASP.NET Core 2.3 at this point.
5:52 So we are actually announcing today the end of support
5:56 date for ASP.NET Core 2.3 for one year from today.
6:00 So April 7th, 2027.
6:02 So it's still still supported for for the next year,
6:05 but after a year the end support will end.
6:07 What does that mean?
6:08 You know, that means no more security fixes,
6:10 no more updates that will be coming to the stack starting in 2027.
6:14 So if you have any old apps that are
6:16 running on .NET Framework and still using ASP.NET Core 2.3,
6:20 we recommend that it's time to start planning
6:22 to to move off of it if you haven't already.
6:24 Hopefully that was the goal anyway, but if you have some old apps that just
6:27 were got stuck on it or you just forgot about,
6:30 go go check them, try and get them upgraded.
6:32 There is of course fortunately today wonderful AI tooling to help out with this.
6:37 We recommend checking out this GitHub Copilot app modernization tooling,
6:41 which is tooling that was specifically targeted at these upgrade
6:44 scenarios to help you move off of, you know,
6:47 old old .NET Framework apps onto the the modern .NET stack.
6:51 So AI can help, so check that out.
6:53 Hopefully it's not too many people that are in this boat,
6:55 but if you're one of those people, it's time to start making a plan.
6:58 Okay, so that's the announcement announcement today.
7:01 Just that end of support for the the old ASP.NET Core 2.3 on the .NET Framework.
7:07 All right, cool.
7:08 All right, so back to the today's topic.
7:11 Let's talk about using Blazer with with Aspire.
7:16 So you know, we've been working closely of course
7:19 with the Aspire folks for a long time.
7:21 I think the Aspire like starter kit app is based on Blazer.
7:25 It has a Blazer web app front end and a API
7:29 ASP.NET Core API back end and all those those pieces.
7:31 You know, Aspire was really built with .NET scenarios in mind,
7:35 but we do know that there are a variety of scenarios that are difficult
7:40 today when you're using Blazer with Aspire
7:42 that we've heard about on the Aspire repo,
7:44 also on the ASP.NET Core repo, that we want to address.
7:46 And so we're doing work on this in the .NET
7:49 11 time frame to address these pain points.
7:51 So some of the pain points that we've heard about,
7:54 it's particularly with Blazer web that with Aspire,
8:12 there are a bunch of friction points.
8:14 You don't get a lot of the niceties that Aspire offers.
8:18 Like the it's a client side application,
8:20 so you don't the the the service defaults that we provide for server based
8:26 applications don't really apply in a lot of ways to a client app like that.
8:30 You really need like service defaults that are
8:32 specific to a Blazer web assembly app.
8:34 Those service defaults should ideally set up a bunch
8:37 of the Aspire features for a client side app app like this.
8:40 Think about like service discovery,
8:41 like how does the Blazer web assembly app discover back end API end points?
8:47 How do you flow that service discovery
8:49 information all the way down to the client?
8:51 You need some sort of config mechanism to flow that that data to the client.
8:55 We don't really have that today.
8:57 Telemetry is a is an obvious a gap when
9:00 you try to add your Blazer web assembly app
9:03 to an Aspire orchestration and then you look at the wonderful
9:06 Aspire dashboard and try to see all your data.
9:08 You don't you don't actually get any data,
9:10 any open telemetry data from your Blazer web assembly app today.
9:14 That's an obvious gap.
9:15 We've heard a lot of people that have stumbled on on debugging.
9:19 Like where they you know, that you try to debug the Blazer web assembly app.
9:22 In Aspire you often launch the application using the Aspire dashboard.
9:27 Like you just click the link, right?
9:28 You see all your resources, your web apps, your back end APIs,
9:31 services, and any other like like Azure resources you're using.
9:34 You go to your app, you click the link,
9:36 and then there's your app and then you try to debug.
9:38 Well, because Blazer web assembly runs client side in the browser,
9:43 in order for us to debug that code,
9:44 we actually have to connect to that browser instance you know,
9:47 to to to look in at that .NET web assembly runtime to see what it's doing.
9:51 That requires setting up the browser
9:52 in a specific way that enables remote debugging.
9:55 When you launch the the Blazer web assembly app from the the Aspire dashboard,
9:59 you don't get that set up and so debugging doesn't work and people get confused.
10:03 It'd be nice if we had a way to launch the app so that debugging actually works.
10:07 But even beyond Blazer web assembly,
10:09 there are scenarios that we think are interesting
10:11 where we could leverage Aspire to make your app,
10:14 you know, more scalable, more idiomatic.
10:16 Like when you're running a Blazer server app,
10:18 you often also need to set up a bunch
10:20 of things to correctly to have it work right.
10:22 Like you need to set up a session affinity or sticky session if
10:26 you need to reconnect from the client back to your circuit on the server,
10:30 you go back to the actually the same
10:32 server instance where your circuit is currently living.
10:35 You need to set that up.
10:35 So we could use Aspire to to help out with with those things.
10:39 So these are a bunch of, you know,
10:40 problems that we've heard about that you know, Javier has been looking at deeply
10:45 and working thinking through solutions for these problems.
10:48 And yeah, Javier, tell us about you know, your thoughts on this space.
10:52 Like how do we make Blazer with Aspire amazing?
10:56 Awesome.
10:57 So yeah, ideally I think our goal is to make
11:02 Blazer and Aspire and Aspire an amazing experience together.
11:08 We think of Aspire as our target
11:11 development or or deploying deployment pipeline.
11:15 Even though Aspire is a development tool, it supports deployment and and stuff,
11:19 but it is our configuration model is um call this the configuration and um is
11:30 essentially an abstraction over many of the other
11:33 things that are out there to do deployments,
11:36 Azure container apps, Kubernetes, Docker, and so on.
11:41 Uh so we want people to think in terms
11:44 of Aspire when they are developing Blazer applications so
11:48 that they can now then leverage all the all
11:52 the information and all the richness that Aspire Yeah.
11:57 provides and and use that uh for their target deployment.
12:01 That way we don't have to be thinking
12:04 about how does it work in this environment?
12:07 How does it work in that environment?
12:08 How does it work in that other environment?
12:10 We target Aspire.
12:12 And I would say and also having your your like
12:14 your agents be able to use that that information.
12:17 Like one of the things I love about using
12:19 Aspire when I'm developing like Blazer apps locally is
12:22 how like Aspire will give you like an MCP
12:24 server which can plug into and collect the the logs,
12:28 the traces, all the diagnostic information that's available in that Aspire
12:32 orchestration and make that information available to like GitHub Copilot,
12:36 your local coding agent.
12:37 So when you're like trying to figure out like why is something not working,
12:40 you just ask your agent and it can go looking through
12:42 all that richness of information and figure things out for you.
12:45 I I think that is it's it's almost magical.
12:47 Like I love that part of using Aspire when I'm when I'm working with Blazer.
12:53 Yeah.
12:54 So as I said, the goal is that we enable all the things
13:00 that we can leverage Aspire for in Blazer
13:03 to make your experience generally better.
13:07 So as you said, there are a bunch of things that are hard today.
13:12 Setting up proxy, setting up sorry,
13:16 setting up service discovery, setting up uh uh telemetry.
13:22 Those are the main two problems that are like hard to do in Aspire with Blazer.
13:28 And what we've done is we've built an integration
13:33 that makes this uh one gesture sort of a speak.
13:38 Uh a one gesture action.
13:43 So let me show you a bit.
13:46 All right, let me pop up in the screen
13:49 for you so people can see what you're showing.
13:51 There you go.
13:53 So give me a second that I'll set up here.
13:56 Uh let me quickly get this thing.
13:59 So I don't want to steal the things.
14:01 Okay.
14:02 So I have an app that I have running already.
14:05 And it's a standalone Blazer web assembly app.
14:11 And we have now this gateway thing which is a new component that we've
14:16 created specifically for allowing you to integrate
14:20 standalone Blazer web assembly applications with Aspire.
14:25 If you look at the things that we've mentioned you can have
14:31 a standalone Blazer web assembly app and you can run it during development.
14:36 But then it comes time it comes a time where you want
14:38 to deploy the web assembly app and you need a server host.
14:42 Yeah.
14:42 And there are multiple options.
14:45 You can go to IIS, you can go to Nginx, you can Nginx,
14:51 you can go to any other server that is out there.
14:56 You can use YARP to deploy and and serve static files.
15:01 But if you do those things,
15:05 you don't get all the benefits of all the things that we
15:09 do in Blazer when your app is hosted to serve the app efficiently.
15:14 You don't get compression.
15:15 You don't get fingerprinting.
15:19 What we do with the gateway is we provide you
15:23 a host which is an upgraded version of our dev server.
15:28 So our dev server is still there,
15:30 but we are going to retire it from the from the default
15:33 template in favor of the of the gateway.
15:36 And the gateway provides an additional set
15:39 of functionalities on top of the dev server.
15:43 It allows you to flow configuration to a web
15:47 assembly app in a way that is configurable.
15:50 It allows you to serve compressed assets and things
15:56 like that from the static web assets pipeline.
16:00 It allows you to like consume
16:03 the fingerprinted endpoints and and the fingerprinted files.
16:08 It flows the configuration from the from the server to the client.
16:12 I don't know if I said that already.
16:15 And in Aspire specifically, with our integration,
16:19 we leverage this in order to flow
16:22 the service discovery and also in order to proxy.
16:27 That's the other thing that I was missing.
16:29 Our gateway also has a built-in YARP proxy
16:33 that is tuned to support serving the service discovery routes.
16:43 So if you are not developing in Aspire and you want proxying for some reason,
16:48 imagine you are developing an app that you have a Blazer front end and maybe
16:53 you have a part of the app that is Angular or a part that is React.
16:59 You can put the proxy on top of it.
17:02 You can configure it and that way you can develop
17:05 as if everything is in the same domain or same origin.
17:11 Same as you would in that deploying so that avoids you
17:15 having to worry about CORS and things like that during development.
17:19 No one wants to have to worry about CORS.
17:21 So putting everything on the same origin is certainly the the desired setup.
17:26 So so you mentioned You mentioned the Blazer development the dev server.
17:31 So that's the piece that like when you create a standalone Blazer
17:34 web assembly app which fundamentally is just like a a static site, right?
17:37 It's just a bunch of static files.
17:38 You need some server to serve those files.
17:41 We give you a component for local development,
17:44 a little basically a little ASP.NET Core server that knows how
17:47 to host those files and it sets up everything right so
17:50 that um those files are served appropriately from a server so
17:54 that you can then browse to it um during during development.
17:58 It sounds like so this Blazer gateway,
18:00 this gateway piece is a component that does that, but then
18:03 will also handle that that use case for production.
18:07 Like when you actually want to go then deploy the application,
18:09 it will give you all the niceties of of of a properly configured server
18:13 for hosting a standalone Blazer web assembly
18:15 app that can be used in production scenarios.
18:17 The current dev server is only meant for local development.
18:19 It's not a it's not a production component, correct?
18:22 Exactly.
18:23 Um our dev server historically has accumulated a bunch
18:27 of dev only specific behaviors that we've worked
18:31 hard over a few releases to like take
18:33 away uh and and re-layer on the right places and this is what allows us to have
18:38 now this clean gateway that is a specialized uh
18:45 host for Blazer uh with its own proxy so
18:48 that you can configure it for many more scenarios.
18:52 It's much more flexible than the dev server.
18:55 And it's also something that you can take
18:58 a straight to production sort of a speak.
19:00 Uh we don't know exactly how that will look like yet.
19:04 We might The current Aspire integration actually does something very clever.
19:10 It uses a single file C# program to build a container.
19:16 So it builds it has the source code of the gateway which is very small.
19:20 It will it builds the single file gateway.
19:24 It publishes and it bakes that into a into a container.
19:30 We'll we'll probably have an out of the box container
19:34 image at some point the same way that YARP has it.
19:37 Um But yeah, what what were you saying, Dan?
19:42 I was we were just talking about I had a I
19:44 was asking about the the dev server versus the the gateway.
19:47 Um and it's kind of cool how you how the gateway is using
19:50 the new single file like like
19:51 functionality and it's actually not super complicated.
19:53 Like it's a fairly simple piece of code.
19:56 Um do you expect that then that gateway replaces the the the local dev server?
20:00 Like do that you would be using the gateway also during local development?
20:04 Yeah, so we I I created a package
20:07 in ASP.NET that is Microsoft.ASP.NET Core Components.Gateway.
20:12 And the gateway is the purpose single server for for Blazor.
20:17 So if you wanted to for example test behaviors where you
20:22 spin up multiple instances of a Blazor server app in different
20:26 ports and you want to put a load balancer in front
20:29 of it to test session stickiness and things like that.
20:34 It's already all all like uh doing a rolling deployment or something like that.
20:40 It's already there so that you can
20:42 do these types of of things during development.
20:44 That's cool.
20:45 So that you can you can use it on your little
20:49 mini front-end cloud cloud that you can like test and test
20:51 with locally by that you've set up using Aspire for both
20:54 local development and then also you can deploy it to production.
20:58 Exactly.
20:58 And that's that's also the the big benefit of of using the gateway
21:03 and and having Aspire baked into it is
21:06 that if you have to configure session stickiness,
21:10 you have to go to every deployment that you
21:15 are planning to do to deploy and do something different.
21:20 Setting up session affinity is different in Nginx and in Nginx
21:24 that is on IIS that is on Kestrel for that matter, that is on any other thing.
21:31 Or different clouds.
21:32 Yeah.
21:33 Exactly.
21:33 Different clouds and so on.
21:35 Even in our own clouds with in many cases
21:38 not done things right and we have enabled this feature
21:42 by default when you deployed and a few versions
21:45 later like something changed and and we broke the feature.
21:49 So this is a way that we have more control and you have more control
21:54 in the sense that if if you put the gateway and you make that your front end,
21:58 you essentially have YARP with extras.
22:04 So those extras are what what I said.
22:08 It's the session affinity so that you don't have to worry about that.
22:13 If you deploy and and you point the traffic to the gateway,
22:16 the gateway will will do the right thing.
22:18 If in the future we want to do smarter things like allowing you to shut down
22:25 a node and stopping the traffic to that node and doing all those things in one
22:32 gesture without you having to orchestrate that workflow
22:37 across multiple components as you would need to do for example if you were using
22:40 Kubernetes or or if you were using something else.
22:46 It would allow us to do things like pause and resume for stopping up
22:52 an instance of your app persisting all
22:55 the state from the live clients into the browser
22:59 having them connect to another instance and then restoring the state so that you
23:03 can cleanly shut down a server instance if you need to do a reboot,
23:06 if you need to do an update things that are
23:10 problematic today or are more challenging today with Blazor server.
23:17 We have a couple questions.
23:18 I'll just bring them on real quick.
23:19 I think these are quick ones.
23:20 Someone was asking about using this gateway with Azure Static Web Apps.
23:26 Um I think that the gateway really is is
23:30 largely serving the role of hosting the static website,
23:33 which is what Azure Static Web Apps does.
23:35 So the gateway would be useful like like
23:37 if you're deploying to like Azure Container Apps,
23:39 the gateway would provide a a a container node
23:42 within that app that handles the static web app hosting.
23:45 So it's kind of they're kind of alternative
23:47 solutions to to to a similar problem.
23:49 There you can deploy Blazor Web Apps Blazor WebAssembly
23:52 Apps to Azure Static Web Apps and that does work.
23:55 It's a static site hosting solution.
23:58 But this is a way that you have sort
23:59 of a generic solution that can be hosted anywhere.
24:02 Like anywhere you can host a container, you'll be able to use this this gateway
24:05 in order to host your Blazor WebAssembly app.
24:07 Anything you want to add?
24:09 Exactly.
24:09 Yeah.
24:09 And you have the keys to your kingdom sort of a speak.
24:12 You are you have the reins of your own destiny.
24:17 Like you don't have to worry about I need to go and configure session affinity,
24:21 I need to configure this, I need to configure that.
24:24 My app is not working because I have set up something during
24:29 development that is not exactly the same during production and so on.
24:34 You have more certainty that there are going to be less
24:38 deltas between your development and your production environment and that should
24:44 give you more confidence in in the fact that like you
24:48 are deploying something that is more that is closer to production.
24:52 Someone else Oh, sorry.
24:54 Yeah, go.
24:55 There was another question about about Aspire's production readiness.
24:59 Like is it is it shipped?
25:00 Is it ready?
25:01 And the answer is yes.
25:01 Yes, for us Aspire has shipped for quite a while now.
25:04 It is production ready.
25:05 You can use it for for production scenarios.
25:07 In fact, internally at Microsoft, we are heavily using Aspire as a orchestration
25:13 system for a lot of our internal applications.
25:16 Like one of the things that's really nice about Aspire is it
25:18 creates these patterns that we can use for rolling out new Azure services,
25:22 rolling out new Microsoft products.
25:24 So we we are using it for production and yes, you can as well.
25:28 Okay.
25:29 Cool.
25:29 Go ahead, Javier.
25:31 Awesome.
25:31 So with that, let me show you a few demos
25:34 of the things that the new integration that we've built enables.
25:39 So let me really quickly go to structured logs.
25:43 And if you see here in structured logs, I have like several tabs that I opened.
25:49 And the telemetry shows here for all the things that the app is doing.
25:54 It's showing like for each individual session it's
25:57 showing a different color and and so on.
25:59 All the structured logs.
26:00 In this case, I'm not doing any particularly any
26:04 particular logging other than what HTTP client is doing.
26:09 Then if I go to traces, I can see also the same thing.
26:15 So I can see things like navigations, I can see on click,
26:21 I can see uh when I go to the weather forecast uh
26:27 there should be here uh I don't know why it's not showing.
26:33 Uh The the Oh, it's here.
26:37 So you can see HTTP requests.
26:38 In this case for example,
26:40 the trace is we are sending the the HTTP request to get the weather forecast.
26:50 And then that is sending a request to the gateway
26:53 which is proxying it to the to the weather forecast.
26:57 So there were This is an interesting design
27:00 decision because there were two ways of doing this.
27:04 We could have given the WebAssembly client
27:10 the URL to talk to the weather forecast directly.
27:17 And that would have saved you technically one hop.
27:21 But the moment we do that you now enter in this like reign of hell that is CORS.
27:30 Uh so your weather forecast app would have to deal
27:35 with CORS and everything and uh uh all your APIs would
27:43 have to be CORS-enabled and you would have to do
27:47 cross-origin requests for all these things and it's just more complicated.
27:51 So by default, we don't do it.
27:54 We set up a proxy for you.
27:57 And the pattern that we follow, if you can see, is we have this app.
28:03 So app is the the actual folder where we are serving the app.
28:08 So if I go here, this is not being served from the root,
28:11 it's being served from the from app folder.
28:14 In this configuration, the gateway is there if you want
28:16 to have like multiple standalone Blazor WebAssembly apps.
28:22 So the pattern is the app name and this is the Aspire
28:26 app name _api and then the other API that you are targeting.
28:31 And whatever you send that way, we send to the we send to the underlying API.
28:36 We proxy to the underlying API and this is exactly what is happening here.
28:42 And how does it know which APIs to proxy?
28:44 Like like does it proxy them all?
28:46 Does it proxy specific ones?
28:47 Like what what does that look like?
28:48 I'll get to that in a moment cuz I want
28:50 to show before that also the other thing which is metrics.
28:55 So we've been doing stuff and you can
28:58 see here like there are no active requests.
29:00 There are like this is the duration of some of the requests that we've sent.
29:05 You can see some Blazor specific metrics.
29:08 I think it's too much time has passed that they don't show up here.
29:13 Uh but you can see navigations or Yeah, I I made this trace like a while back so
29:21 maybe the this slider has just gone too far away.
29:25 But in general, things will show up.
29:27 In fact, let me just I was going to click
29:30 but the other thing is that metrics are not instant.
29:33 Metrics are only sent to the telemetry endpoint about every 60 seconds.
29:41 Okay, because if not you would be spamming your server
29:44 with metrics and you don't want to do that.
29:46 Uh but me, if you do this, they will show up here.
29:52 So today, if you create a Blazer Web Assembly
29:53 app and try to do what you're showing here,
29:55 like see metrics, see traces, see like none of that stuff currently shows up.
30:00 In In fact, I just realized I just did last
30:03 hour and you can see here the metric up here.
30:05 Nice.
30:06 And navigations too, the render this too, the leaf sizes.
30:13 This is actually the first time I'm seeing the metrics working here.
30:16 So this is this is cool.
30:17 It's great great to see Javier.
30:18 Nice.
30:20 Now, uh some people are asking about um like, "Hey, how do I get this?
30:23 Where where where is there like some template with this gateway?"
30:26 So the the bits that we're showing you right now, this is uh work in progress.
30:30 Like we are actively working on improving
30:33 the Blazer Web Assembly and Blazer integration with Aspire.
30:35 So these bits aren't actually publicly available yet for you to try out.
30:39 Um but I have that copy there.
30:41 Oh, sorry.
30:42 They are publicly available.
30:44 And you can actually go and try this because this is not a .NET 11 app.
30:47 This is a .NET 10 app.
30:49 Uh so there is a PR that I have.
30:54 Let me just [snorts] go and find Let me find the PR.
30:59 But you can get access to this to these bits because it's all configuration.
31:03 We are working on making it nicer.
31:07 Uh but the underlying pattern is something
31:10 that you can definitely You set it up yourself.
31:13 You can do it yourself.
31:14 Yes.
31:16 Uh so I'm trying to find the PR.
31:25 Which is here.
31:27 But it is so just to what I was saying before, it is a a a work in progress.
31:32 Like the actual like um you know,
31:35 full user experience is something that we're working on shipping and providing.
31:40 Uh so we will We have appropriate templates and such.
31:42 Like we are working on a Blazer Web
31:44 Assembly uh service defaults template that you can have,
31:47 giving you the gateway component as a pre-built thing.
31:49 You know, those that that whole set
31:51 of technologies are something we're working on shipping.
31:54 But the point of these standups is to give the community early uh early views
31:58 of what we're working on as a team so that we can hear your feedback,
32:01 see if we're on the right track,
32:03 uh so you guys can uh participate You folks can participate
32:06 on the edge of development as we work on ASP.NET Core and Blazer.
32:09 So these are these are early bits that you're you're seeing right now.
32:12 Exactly.
32:13 It's definitely not uh not the end experience and it's not uh ultra polished,
32:18 but if you want to get uh this working today,
32:22 you can go to this PR and you can like
32:26 read the code and and follow the the things that it
32:30 says here and and you have all the all the details
32:33 about how how this how our Aspire integration works essentially.
32:38 Nice.
32:39 It's the benefit of open source development.
32:42 Yep.
32:44 So we talk about structured logs, we talk about traces, we talk about metrics.
32:50 Let's talk a bit about how this actually works.
32:55 If I go here, this is the Aspire
32:59 configuration that or the Aspire integration that we created.
33:04 So you have your builder, you have your weather API.
33:09 Then we have this new add Blazer
33:11 Web Assembly project or add Blazer WASM project.
33:15 And here we set up the reference for the weather API.
33:20 And then our new gateway is behind this add Blazer gateway integration.
33:28 You can configure the endpoints for the for the gateway
33:32 and then you configure telemetry for it.
33:35 And then you say, "Hey, here's a client Blazer app that I want Here's
33:39 a client app that I want you to to serve."
33:42 And you can see here that there is this like
33:45 app which is the name for the Blazer app.
33:49 And this is the default for serving the app under that app prefix.
33:56 All these uh stuff is is overridable, I believe.
34:00 Um I don't remember because I did I don't remember exactly because I wrote
34:05 this code 2 weeks ago or more and since everybody's using LLMs right now,
34:11 I write way more code.
34:13 So I don't remember the exact
34:15 details of all the extensibility extensibility options.
34:19 But you can configure the prefix,
34:20 you can configure the services that get proxied,
34:23 you can configure the things that don't get proxied and and you
34:26 have full control over the over the things that you can do here.
34:32 So it's because that client So like that the two have
34:34 You have your gateway which is hosting the Blazer Web Assembly client.
34:38 And then the Blazer client is is referencing the the weather API.
34:43 And and that's Is that what flows to to set up the proxying?
34:45 That's what tells the gateway like, "Hey,
34:47 this is an endpoint you should actually
34:49 make available as a public endpoint." Exactly.
34:52 Um We do it in a way where we only
34:57 make the weather API available to the Blazer API and we
35:02 don't we only make the gateway If we had a second
35:07 app and and it all had a different API reference,
35:11 we only make that other API reference available to that other app.
35:16 Available in what sense?
35:16 Like through service discovery or like even as Yeah, through service discovery.
35:20 Yeah.
35:20 But like it's a public endpoint, right?
35:21 Like if someone found Yeah, it is it is a public endpoint.
35:24 It's not a security measure or anything like that.
35:26 It's just reflecting that each app gets the scope
35:29 configuration for the things that it sets up.
35:32 Makes sense.
35:33 So that is the standalone uh scenario,
35:37 but there's another scenario in which you already have an ASP.NET Core host.
35:41 And this is Blazer with Aspire hosted.
35:46 And the code is very similar.
35:47 It's just slightly different.
35:50 So in here, you don't see the gateway.
35:53 And the reason you don't see the gateway
35:54 is because you already have a Blazer host.
35:59 So we use that.
36:01 So in your Blazer host,
36:03 we now have this proxy service and and this proxy telemetry.
36:10 And these are the helpers that tell
36:14 Aspire configure configure the the environment
36:21 to uh enable service discovery and to proxy this information to the client.
36:26 And if we go to the server,
36:30 this actually shows what the gateway does because the gateway
36:34 does the same thing that your server app will do.
36:38 And that's by definition, so to speak.
36:42 Um is Sorry, by design.
36:46 We want the We want the gateway to do the same thing as the as the server app.
36:52 So map static assets and then there is an add default endpoints here.
36:59 So well, you can see the the add reverse proxy here for your app.
37:04 And this is literally got what the what the gateway does to configure your app.
37:09 Uh Uh you see map reverse proxy here
37:12 and and there is this map default endpoints.
37:15 And uh map default endpoints is in this service defaults, I think.
37:21 And this is the standard Aspire pattern.
37:25 Let me see.
37:27 Map default endpoints here.
37:30 Yeah, so we map the health checks.
37:33 And we have this additional configuration endpoint.
37:39 Which we set up in this client config endpoint path and and config response.
37:47 And we simply set up a new endpoint
37:50 in that config path that serves that config response association.
37:54 So our integration already generates our JSON document that has all
37:58 the information that is needed for the Web Assembly app to to boot.
38:03 And this is the exact same thing that happens
38:05 on on a standalone app using the gateway.
38:10 Now, there is a different thing There is a small difference here,
38:15 which is in the future, in .NET 11, we will not have this endpoint because
38:20 we will automatically flow this configuration embedded
38:24 directly within the document so that your app doesn't have to do an extra jump.
38:29 The way the the configuration works in Aspire today or how the client picks
38:35 this configuration up is there is this JS
38:38 initializer here that when the app builds,
38:44 it issues an HTTP request to get the configuration and then goes
38:48 ahead and configures all the environment variables in the Web Assembly process.
38:53 And since we have configured Web Assembly the the Web
38:57 Assembly host to use environment variables for configuration,
39:02 then all the service discovery and everything
39:05 is already in the config in the configuration
39:07 and and HTTP client factory and other
39:11 elements of the pipeline pick it up automatically.
39:15 Same as they would in server.
39:16 I remember the first time I saw this and I was like, "What?
39:19 Environment variables?" Cuz cuz this is a this is
39:21 a JavaScript initializer that's being loaded on the client,
39:24 like in the in the browser, and then setting up environment variables.
39:28 Like what does an environment variable even mean like in a in a browser app?
39:31 But there is sort of a a mocked notion of a environment variable, I guess.
39:34 Is Is that right?
39:35 Like Yes, it's it's exactly that.
39:38 .NET running on Web Assembly is nothing less than an executable
39:44 as if you were running on a regular machine sort of a speak.
39:48 It has a sandbox, but the concepts exist and there are two things
39:52 that you can do with the concepts that are not native to the platform.
39:56 You can throw an exception and say, "Hey,
39:59 I don't support this." Which happens for many APIs.
40:03 Or you can say, "Well, there's actually a way in which I can simulate
40:07 this." And it's useful to simulate this because imagine
40:12 how many libraries would not work if the actual
40:16 hosting web assembly didn't support reading an environment variable.
40:20 Yeah.
40:20 And I think there's even things like simulating a file system and stuff.
40:23 There's all sorts of fun things that get to emulated
40:26 on the web assembly side to make like patterns like this work.
40:29 Okay, so so that was a lot though.
40:30 Like let's let's let me let's step back a bit.
40:32 Let me make sure everyone followed all of that.
40:34 So on my on the server, we showed two cases.
40:38 You showed the the gateway case and then
40:40 ASP.NET Core hosted Blazor WebAssembly app case.
40:44 And you were showing how the code for how you set things up on the server,
40:48 whether it's the gateway or the server, it's the same.
40:50 Like you're setting up static web assets,
40:53 you're setting up this configuration endpoint to flow
40:56 config data from the server to the client.
40:59 Like for example, the service discovery data.
41:01 Like where is the API endpoint that is
41:04 currently being proxied for you from the back end.
41:06 Where where how does the client call that API endpoint?
41:09 Service discovery config data would allow the client to figure that out.
41:12 But how do you flow the config data?
41:14 The answer is we're setting up this config endpoint for you.
41:17 And it sounds like in the future
41:18 that might even get more integrated into the stack.
41:20 And in order to pick up that config data,
41:23 I think you're saying that we provide a piece
41:26 of JavaScript set up as a JavaScript initializer,
41:28 which is like a it's like a piece of JavaScript
41:30 that just automatically gets loaded by by Blazor, right?
41:33 Like on server on on on on Yeah.
41:34 startup.
41:35 And that initializer is then grabbing the config data and setting
41:39 it up as environment variables as emulated environment variables in the browser.
41:44 And then when the .NET WebAssembly runtime boots up,
41:46 it sees those emulated environment variables,
41:48 makes them available as config data to the client,
41:51 and then the normal configuration system like Microsoft extensions configuration
41:56 that I configuration stuff kicks in, reads the environment variables,
41:59 and now you've got your your service discovery endpoints.
42:02 You know how where to make an API call.
42:04 So is that right?
42:04 Did I Did I get it end to end?
42:06 Exactly.
42:07 And uh Easy peasy, right?
42:09 Like no no Exactly.
42:12 [laughter] The I I As I said, in 11,
42:14 we are actually uh providing an out-of-the-box way of flowing
42:20 uh browser configuration from the server to the client.
42:24 Yeah.
42:24 And it's not limited to WebAssembly.
42:27 So it allows you to configure things like if you want
42:31 SSR on enhanced nav and things like that when the app starts.
42:39 Okay.
42:40 So yeah, if you if you need to for example disable an enhanced navigation today,
42:45 you have to go manually boot Blazor instead
42:48 of of just having the script in the page.
42:51 You need to uh tell it to to not start and then you
42:56 need to have an extra a script that says Blazor.start and provide the options.
43:02 There are some options that we cannot give you values for, but uh for or options
43:07 for because they are callbacks and things like
43:09 that that don't make sense in in JavaScript.
43:12 Uh sorry, that cannot be serialized.
43:15 But for things like the login level, the server SignalR settings,
43:23 the few of them that like you can control on the options,
43:27 the enhanced nav, the WebAssembly settings,
43:31 you can do that you can send those things
43:34 to the client now whether or not you're using Aspire.
43:39 It's a it's a more general purpose feature to allow
43:43 you to do things that were kind of like
43:47 cumbersome to achieve in a in a much simpler
43:51 way and that also enables powering Aspire in the process.
44:00 Okay, we've got a bunch of questions in the chat.
44:02 Do you do Should we take some questions or do you do
44:04 you want to Do you have more more you want to show first?
44:06 do questions.
44:07 Okay, let's do some some questions here.
44:09 So uh from Robson, uh in case of replicas on the API side,
44:15 is the gate Does the gateway handle all of them?
44:17 And what about SignalR?
44:18 Any thoughts on that?
44:20 Yes.
44:21 So uh the the role of the gateway is essentially to be your front end.
44:26 And I haven't showed it here, but with a bit of YARP configuration,
44:34 you say for example, here's my Blazor server app with replicas,
44:40 and then we would have something like add Blazor server app
44:46 in the gateway project and that will automatically make sure that we configure
44:53 the the URL of the gateway either on the either on the root
44:59 or either on on a path that you specify to serve your Blazor app.
45:04 So that it load balances all
45:06 the all the connections across the different instances.
45:12 Okay.
45:13 All right.
45:14 Then someone was asking about um containers versus
45:21 I think it's basically uh versus app service.
45:23 So traces are valuable, but deploying to a container,
45:26 I'm using app service for API and standalone WASM.
45:29 Um so I I guess this one amounts to like what's Aspire's support
45:33 for deploying to Azure App Service versus
45:36 like natural container app style style into environment.
45:39 I mean, app service does also support uh containers.
45:41 And I think they have I honestly don't remember.
45:44 I know they they had gotten this request a number
45:46 of times and I thought they had actually worked on it.
45:48 I don't remember if it's actually shipped.
45:50 So we'll have to check with the Aspire folks what their app service story
45:54 is um to see if that's something they already have support for or not.
45:58 Um but conceptually that all the deployment
46:00 information should be available from the app host.
46:02 So you could roll it yourself,
46:03 but whether it's a first-class scenario, I I don't actually remember.
46:06 Javier, do you know?
46:07 Do you remember if what what Aspire's done for app service?
46:10 Uh I don't remember,
46:13 but I definitely tell you that it's super easy with Aspire to say Aspire publish
46:19 and it will generate a a manifest that then you can do deploy and other stuff.
46:23 Do your own thing.
46:25 Yeah, folks in the chat, if you know, feel free to chime in.
46:27 I I don't remember off the top of my head.
46:28 But if they haven't done shipped it yet,
46:30 I know they've had it had the request a number of number of times.
46:32 So go to their their new repo in the Microsoft org, microsoft.com/aspire,
46:37 and uh see what the where the issues are at related to app service support.
46:42 So there there's an interesting question question on the chat uh
46:47 that is Guillaume asking about Aspire and creating a Docker Compose equivalent.
46:53 I want to touch on that because I think that that highlights a lot
46:57 of the value that Aspire brings into the the table because I did
47:03 Yes, I did this exactly.
47:05 Okay.
47:06 So Aspire essentially abstracts uh all the setup
47:11 that you have to do for your services.
47:15 When you do Aspire publish, nothing gets published.
47:18 You get a manifest that essentially has all the ways
47:23 in that in in which your app uh needs to configure things.
47:28 It it exposes the relationship between services and and how
47:31 things need to flow into each one of the services.
47:34 But then you are completely free from using
47:38 that with Kubernetes or uh using that with anything else.
47:42 In fact, I pointed my LLM, "Hey, I have this Aspire manifest.
47:48 Can you go and create me a Docker Compose file so
47:51 that I can just run Docker Compose app." I went and did it,
47:55 and this is the like magic of it.
47:58 So this was this was a question a response
48:00 to this question about like Blazor with Aspire.
48:03 Does it require Azure for deployment or can it
48:05 run anywhere like you could deploy it on IIS?
48:06 So the answer is yes.
48:07 The The deployment model is flexible.
48:10 Like you get a manifest and you can then deploy Now granted,
48:14 Aspire has more sort of built-in support for certain environments.
48:17 Like I think they really started with Azure Container
48:19 Apps as a a very convenient way to to deploy,
48:22 but the deployment system is designed so
48:24 that it's flexible that you can deploy anywhere.
48:26 I think they like the AWS folks recently added
48:28 the support for deploying to to Azure Web Apps.
48:31 Sorry, to Amazon Web Service as a as an alternative.
48:35 You know, things like that.
48:36 It's a it's a flexible deployment model.
48:39 Yeah, I'm definitely not an Aspire an Aspire expert to that level,
48:43 and I have probably uh botched a bunch of the things that I've said,
48:47 but the idea is that yes,
48:48 it's very flexible and then you can write some programmatic code that takes
48:52 this manifest that Aspire produces and adapts
48:56 it adapts it to your like target environment.
49:00 Great.
49:01 All right.
49:02 Uh another question.
49:04 Um someone was back to the like um Azure Static Web Apps topic.
49:08 Someone was asking like is it is it faster hosting on Azure
49:11 Static Web Apps than hosting your files in in a container?
49:14 Um I mean, for this I would say like yeah,
49:16 Azure Static Web Apps is a bespoke service specifically for that scenario.
49:20 So obviously they do a bunch of optimization around uh hosting static web apps.
49:24 So if if that's an option for you, then then great.
49:27 Yes, you can can absolutely use that and you'll
49:29 get the the benefits of of that specific service.
49:32 Uh but as Javier was mentioning earlier, the the By in your own container,
49:36 you get a a level of flexibility and control that you
49:39 don't otherwise get when using a a specific service that way.
49:42 So, both options are available.
49:44 One gives you more flexibility,
49:45 one gives you sort of a catered specific experience.
49:49 Is there extra mile performance sort of a speak?
49:53 If you need to go the last mile of performance,
49:55 you'll probably optimize everything, put on a CDN, and and do things like that.
50:01 But in many cases, that's not where you start.
50:06 So, someone was asking, and I'm not sure I get this question.
50:08 I I I I doesn't Someone's saying they don't understand why this is needed.
50:11 I assume they're referring to the gateway.
50:12 Why Why not just use a back end for front end?
50:14 Or is this exactly that?
50:17 So, the gateway is exactly that.
50:19 It's It's back end for front end.
50:21 It proxies your APIs to the right places.
50:26 It flows the configuration from from the environment so
50:30 that the app on web assembly can easily talk to services.
50:34 It acts as a coordinator,
50:36 and it also ingests all the telemetry that client sends,
50:42 and and sends them to your telemetry endpoint.
50:46 Yeah, I think it's fairly common pattern.
50:47 Like like the API management style style patterns is
50:50 very very similar to to what we're doing here.
50:52 Yeah.
50:53 Which uh And as we said earlier,
50:56 we could have flown the the configuration for your API
50:59 to talk directly to your weather API service,
51:03 but then you're going to enjoy the course.
51:05 Right.
51:06 Yeah, you know, the the same same origin constraints of browsers.
51:09 It's nice to to behave to play nice with with that constraint.
51:13 Speaking of API management, someone specifically asked like,
51:15 how do I integrate this with an existing API management gateway?
51:18 Like, what if you are using like Azure's API management solution?
51:22 I don't know.
51:22 Do you have any thoughts on that, Javier?
51:24 Yeah, so I mean, you can compose proxies,
51:27 and essentially you put your API management proxy,
51:31 and then proxy the traffic to the gateway,
51:33 and then from the gateway to the to the back end service.
51:37 Because ultimately, the goal of the gateway is to hide
51:42 the complexity for the web app from from anything else,
51:47 and to make the deployment more agnostic.
51:52 You can always pay to to do something specific to your target deployment.
51:57 Cool.
51:58 And then Uh some just general Blazer love coming
52:04 in from I'm loving the Blazer after the last couple of weekends.
52:07 Really good developer experience.
52:08 Thank you.
52:08 Glad you're you're enjoying that.
52:10 That's fantastic to hear.
52:12 Um and then question here from Corto.
52:17 So, the gateway intercepts the request before it reaches the web API.
52:21 So, you have the option to save all data for telemetry.
52:24 Um yeah, so it's a proxy.
52:25 It's proxying all the the requests.
52:27 The telemetry will get handled like Aspire will
52:30 wire up open telemetry for all the different sources.
52:33 So, you'll get telemetry on um on both sides, both the requests being made,
52:37 and then the requests being received and and processed.
52:39 So, that's when you saw at the the tracing
52:41 that Javier showed in the Aspire dashboard,
52:43 it was showing the full trace end to end
52:45 from client to to server through the gateway process.
52:48 Yeah, let me see if I can like bring that back.
52:57 Let's say if I go here and show there is a price for this.
53:02 Yeah, this one.
53:03 Oh, yeah, you see the the navigation, and then you see the the HTTP client here.
53:09 If you click, you see the request.
53:10 This is essentially what what gets sent to the telemetry.
53:18 And obviously, there is the URL.
53:20 You're not going to get the body, I think.
53:23 You should probably also not save the body
53:26 in your telemetry unless you are very rich.
53:30 If you have way If you have a lot of dollars to to burn,
53:34 then yes, save everything.
53:38 [laughter] Yeah.
53:38 Yeah.
53:39 All right, cool.
53:40 All right, I think that is the last question there.
53:44 Uh and then we are getting close to the end of time.
53:47 I guess the the final question I'll ask on behalf of our viewers,
53:51 Javier, is when when will this like ship?
53:53 Like, when when when when are we targeting to actually
53:55 have this be available in a uh first-class way?
54:00 Uh so, obviously, we would say uh .NET 11 is the is the milestone,
54:07 but the integration is is already out on PR, as you've seen in the Aspire repo.
54:14 So, we are going through the motions of getting that merged,
54:17 and that would flow into the regular Aspire release vehicles.
54:24 And they don't So, I mean, this is .NET 11 timeframe.
54:27 Uh the the things that we are are
54:29 pushing into Aspire for like specific Blazer integrations,
54:32 you know, Aspire ships on an independent schedule from from the .NET platform.
54:37 So, they I think they just shipped 13.2 and updates to 13.2.
54:42 So, this can roll into the next Aspire release,
54:45 and they they ship fairly fairly frequently, unlike the platform,
54:48 which moves a little slower so that, you know,
54:50 you have a more stable foundation that you're that you're building on.
54:54 So, in .NET 11 is November of this year,
54:57 end of this year is when we will ship the the platform updates,
54:59 but the pieces that are Aspire specific that are shipping in Aspire might will
55:03 likely ship sooner than that, and um not even necessarily have an 11 dependency.
55:07 Is that Is that correct?
55:09 Yeah, in fact, the app that you saw is a .NET 10 app.
55:14 Everything is already there.
55:15 You just need to know how to put it together.
55:19 And then there's also templates like like the service defaults templates.
55:23 Will those those would ship in like Would those potentially ship in the SDK?
55:26 Or um or would they ship
55:29 the the service default templates, I don't know if they will ship on on the SDK,
55:33 or if we will make them ship out of band uh to make them available uh sooner.
55:40 With that Those Those are things that that we need to decide,
55:44 but all these things are essentially glue code.
55:48 It's as I said, everything is there, everything works.
55:51 It's a matter of knowing how to put things together,
55:54 and how to how to get things wired up in in the way that they compose
56:01 the most so that you don't end up
56:03 with like 5,000 5,000 lines of code in your app.
56:06 Fantastic.
56:07 Okay.
56:08 Well, thank you very much for coming and showing
56:11 us the latest uh Blazer integration for Aspire.
56:15 Looks great.
56:16 I know I'm super excited to to be able
56:18 to have this experience for my own Blazer development.
56:21 Uh if you haven't tried out Aspire yet,
56:23 folks, I strongly recommend you give it a shot.
56:25 Like, Aspire is just so nice.
56:27 Like, it gives you such a fantastic local development experience.
56:31 Really helps with you know, telemetry and observability,
56:35 and then deployment, very flexible deployment model.
56:38 Definitely give it a shot.
56:39 And I think that's what we had for today.
56:42 Thank you everyone for for watching, and we will I guess see you next time.
56:46 Thanks, Javier.
56:48 Awesome.
56:48 Thank you.
56:49 Bye-bye.