Transform Application Development with .NET Aspire: Seamless Integration with JavaScript and Node.js

  • Thread starter Thread starter Glaucia_Lemos
  • Start date Start date
G

Glaucia_Lemos

thumb-aspire.jpg



In the ever-evolving landscape of cloud application development, managing configurations, ensuring resilience, and maintaining seamless integration between various components can be quite challenging.



This is where .NET Aspire comes into play! A robust application development framework designed to simplify these complexities, allowing developers to focus on creating features rather than dealing with extensive configurations.



In this article, we will explore the core aspects of .NET Aspire, examining its benefits, the configuration process, and integration with JavaScript, as presented in an outstanding session at the recent .NET Aspire Developers Day by Chris Noring, Senior Developer Advocate at Microsoft.



.NET Aspire Developers Day​




The latest .NET Aspire Developers Day, which took place on July 23, 2024, was a great event with lots of technical and practical sessions, featuring different programming languages and frameworks. The main goal of this online event was to show how easy it is to develop modern applications with the power of .NET Aspire!



No worries if you missed the event! Here's the link to the recording so you can check out and learn more about .NET Aspire and how it can help you in different software development situations.



.NET Aspire Developers Day Online Event



So, what exactly is .NET Aspire? Let's dive in and find out more!



Understanding .NET Aspire​




aspire.jpg



.NET Aspire is a cloud-ready framework that helps you build distributed and production-ready applications. It's got NuGet packages that make it easier to build apps that are made up of small, connected services, which are called microservices.








Purpose of .NET Aspire​




.NET Aspire is all about making the development process easier, especially when it comes to building cloud-based apps. It's got tools and patterns that make everything easier, from getting set up to running distributed applications. And also, .NET Aspire makes orchestration simple. It automatically connects projects and their dependencies, so you don't have to worry about the technical details.



Simplified Orchestration​




aspire-save.png



Orchestration in .NET Aspire is all about making your local development environment easier to use by automating the configuration and interconnection of multiple projects and their dependencies. It's not meant to replace the kind of robust systems you'd use in production, like Kubernetes. What .NET Aspire does is provide abstractions that make it easier to set up services, find them, and configure containers.



Ready-to-Use Components​




key-components-aspire.png





.NET Aspire also comes with ready-to-use components like Redis or PostgreSQL that you can add to your project with just a few lines of code. Plus, it's got project templates and tools for Visual Studio, Visual Studio Code, and the .NET CLI, so it's a breeze to create and manage your projects.



Usage Example​




For instance, you can add a Redis container with just a few lines of code and set up the connection string automatically in the Frontend project.







Code:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
builder.AddProject<Projects.MyFrontend>("frontend")
       .WithReference(cache);







If you want to learn more about .NET Aspire, I suggest checking out the official documentation. It's got all the details and examples you need to get started developing with .NET Aspire.



Access the official .NET Aspire documentation now: Official .NET Aspire Documentation



docs-aspire.png



Getting Started with .NET Aspire with JavaScript​




At the .NET Aspire Developers Day session, Chris Noring showed us an amazing integration between .NET Aspire and JavaScript. He demonstrated how we can use the power of .NET Aspire and the flexibility of JavaScript to create modern, distributed applications.



If you would like to watch Chris Noring's full session, just click on the link below:








He started off by showing us how simple it is to get started with .NET Aspire. All you need to do is install a few things:






pre-requesites.png



It's really straightforward to set up a .NET Aspire project. You can use Visual Studio, Visual Studio Code, or just the terminal.



For instance, you can create a new project using the terminal with this command:







dotnet new aspire-starter







This command puts together a project structure that includes the main bits and pieces you need, like AppHost (the brains of the operation), ServiceDefaults, and a starter application.



Once you have got the project structured, the next thing to do is to run it. Before you get started, you'll need to make sure that HTTPS is enabled, because .NET Aspire needs HTTPS to work.



To get HTTPS up and running, you can use this command:







dotnet dev-certs https --trust







To get the project up and running, just use the command:







dotnet run







When you run the AppHost project, you'll see a dashboard with all the resources in your project, like APIs and Frontend services. This dashboard gives you a great overview of your application's metrics, logs, and active requests, making it easier to monitor and debug your cloud application.



Chris Noring showed us all this at his session at .NET Aspire Developers Day. He made it look really easy and practical to start developing modern applications with .NET Aspire.



chris-demo.png



If you like, I recommend reading the tutorial: "Quickstart: Build your first .NET Aspire project" available in the official .NET Aspire documentation.



More on Orchestration with .NET Aspire​




orch-manifest.png



Let's take a closer look at what Chris Noring shared in this part of the session.



Orchestrating distributed applications with .NET Aspire is all about setting up and linking the different parts that make up the application. The aspire-manifest.json file is key to this process. It shows how the services connect and configure within the application.



This automation makes life easier for developers, so they don't have to manually configure each connection and dependency.



The Role of aspire-manifest.json



The aspire-manifest.json is a JSON file that's automatically generated by .NET Aspire. It contains all the necessary info about the app's resources and components.



It's got all the details you need, like connection strings, environment variables, ports, and communication protocols. This manifest makes sure all the app's services connect right and work together smoothly.



Let's take a look at the example Chris Noring showed us in the session on how to configure a Redis cache and a Node.js Product API using the Program.cs file.







Code:
var cache = builder.AddRedis("cache");

var productApi = builder.AddNpmApp("productapi", "../NodeApi", "watch")
    .WithReference(cache)
    .WithHttpEndpoint(env: "PORT")
    .WithExternalHttpEndpoints()
    .PublishAsDockerFile();







In this example, Redis is configured as a cache service, and the product API, developed in Node.js, is configured to use this cache. The WithReference(cache) method ensures that the product API can connect to Redis. The PublishAsDockerFile() method creates a Dockerfile for the application, allowing it to run in a container.



How Does the Manifest Reflect These Configurations?​




Once you have run the code, .NET Aspire will create an aspire-manifest.json file that shows all the settings you've configured in the code. Chris goes over how the manifest shows the Redis and Product API configuration:







Code:
{
  "productapi": {
    "type": "dockerfile.v0",
    "path": "../NodeApi/Dockerfile",
    "context": "../NodeApi",
    "env": {
      "NODE_ENV": "development",
      "ConnectionStrings__cache": "{cache.connectionString}",
      "PORT": "{productapi.bindings.http.port}"
    },
    "bindings": {
      "http": {
        "scheme": "http",
        "protocol": "tcp",
        "transport": "http",
        "targetPort": 8000,
        "external": true
      }
    }
  }
}







In this part of the manifest, we can see that the Product API (productapi) is set up to use the Redis connection string (ConnectionStrings__cache), which is automatically generated and added to the application's environment. On top of that, the manifest says that the Product API will be available via HTTP on port 8000.



How to Create or Update the Manifest?​




If you want to generate or update the aspire-manifest.json file, you can use this command:







dotnet run --publisher manifest --output-path aspire-manifest.json







This command runs the application and generates the manifest, which is essential for deployment in production environments or testing during development.



Integrating JavaScript with .NET Aspire​




aspire-javascript.png



.NET Aspire is flexible enough to work with JavaScript, so you can use it for both front-end and back-end development. This lets developers use popular JavaScript frameworks and libraries with .NET components, creating one unified development environment.



Front-End Example with Angular​




aspire-angular.png



Chris Noring showed us how to integrate .NET Aspire into a front-end project developed in Angular. You can make backend configuration and API connection easier by using environment variables. These are automatically generated and injected into the project.



Backend Configuration in Angular​




The proxy.conf.js file is used to redirect API calls in the development environment to the right backend. The backend URLs, which can be different in each environment, are managed using environment variables. Here's an example of how it's set up:







Code:
module.exports = {
  "/api": {
    target: process.env["services__weatherapi__https__0"] || process.env["services__weatherapi__http__0"],
    secure: process.env["NODE_ENV"] !== "development",
    pathRewrite: { "^/api": "" },
  },
};







In this example, we are setting the target based on the environment variables services__weatherapi__https__0 or services__weatherapi__http__0, which are automatically injected by .NET Aspire. This configuration makes sure that the Angular front end can connect to the backend service no matter what environment it's in (development, test, or production).



Using HttpClient in Angular​




In Angular, you can interact with the backend using the HttpClient service, as shown in the following example:







Code:
constructor(private http: HttpClient) {
  this.http.get<WeatherForecast[]>('api/weatherforecast').subscribe({
    next: result => this.forecasts = result,
    error: console.error
  });
}







This snippet shows how the call to the api/weatherforecast API is automatically redirected to the correct backend, thanks to the configuration made in proxy.conf.js. This makes it easier for the Angular frontend and the backend to communicate, and it makes sure that the environment variables set up in the .NET Aspire manifest are used correctly.



Integration with Node.js and .NET Aspire​




.NET Aspire makes it easy to manage .NET apps and also lets you easily add other technologies like Node.js. This flexibility lets you build distributed apps that combine different tech stacks in a really efficient way.



Orchestration in AppHost​




node-aspire-01.png



In the orchestration performed in AppHost, .NET Aspire makes it easy for you to connect different components of your application, such as a Node.js Frontend and a Backend API.



In the second image, you can see how AppHost is configured in the code.







Code:
var cache = builder.AddRedis("cache");

var weatherapi = builder.AddProject<Projects.AspireWithNode_AspNetCoreApi>("weatherapi");

var frontend = builder.AddNpmApp("frontend", "../NodeFrontend", "watch")
    .WithReference(weatherapi)
    .WithReference(cache)
    .WithHttpEndpoint(env: "PORT")
    .WithExternalHttpEndpoints()
    .PublishAsDockerFile()







In this example, we've got Redis as the cache, the weatherapi for the weather forecast API, and the frontend is the Node.js application. The WithReference() function links everything together, so the frontend can access both Redis and the API.



Using PublishAsDockerFile() lets you package the frontend as a Docker container, which makes it easy to deploy in any environment.



In the Node.js Application...​




node-aspire-02.png





In the example shown in the images, the Node.js app is set up to get the cache address and API URL straight from the Aspire project.

This is done through environment variables that are automatically generated based on the resources defined in the .NET Aspire manifest.







Code:
const cacheAddress = env['ConnectionStrings__cache'];
const apiServer = env['services__weatherapi__https__0'] ?? env['services__weatherapi__http__0'];







.NET Aspire automatically injects environment variables like ConnectionStrings__cache and services__weatherapi into the Node.js application's runtime environment. These variables have the info needed for the app to connect to Redis and the weather forecast API correctly.



With this info, the app can easily access the cache and the API without having to hard-code URLs or connection strings. This makes it easier to maintain the code and also makes sure the application works correctly in different environments (development, test, production).

Example of Usage in an Express Route​




Here's an example of how this configuration is used in an Express route in a Node.js application:







Code:
app.get('/', async (req, res) => {
    let cachedForecasts = await cache.get('forecasts');
    if (cachedForecasts) {
        res.render('index', { forecasts: JSON.parse(cachedForecasts) });
        return;
    }

    let response = await fetch(`${apiServer}/weatherforecast`);
    let forecasts = await response.json();
    await cache.set('forecasts', JSON.stringify(forecasts));
    res.render('index', { forecasts });
});









The app first checks the Redis cache for weather forecasts. If the data is in the cache, it's displayed right away. Otherwise, the app makes a request to the weather forecast API (apiServer), stores the results in the cache, and then displays them.



This logic really speeds up the app and makes it more efficient, so data is retrieved from the cache as quickly as possible.



Wrapping Up​




.NET Aspire is a great tool for building modern apps, especially those that use cloud-based, distributed systems. It gets rid of a lot of the complexity that comes with orchestration, service discovery, and environment configuration, so developers can focus more on writing business logic and less on managing infrastructure.



It's also great that it works seamlessly with JavaScript and Node.js. This makes it a really useful tool for building robust, scalable apps that can work across different tech stacks.



If you're looking to make your development workflow easier while making sure your apps are ready for the real world, .NET Aspire is worth checking out.



Don't miss the opportunity to dive deeper into .NET Aspire's capabilities. Watch the full session by Chris Noring at .NET Aspire Developers Day to see these concepts in action and learn more about how you can leverage this powerful framework in your projects.






Additional Resources​




If you're looking to keep learning and getting more proficient in .NET Aspire, here are some additional resources to help you out:






I hope this article has been helpful and inspiring for you. If you have any questions or suggestions, please feel free to share them in the comments below. I'm here to help and support you as you learn and grow professionally.



Until next time! Keep learning, creating, and sharing! :cool:

Continue reading...
 
Back
Top