Blazor Community Standup | Blazor integration with Aspire

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.

Study with Looplines Download Captions Watch on YouTube