In this blog post, we’ll guide you through building a Weather Forecast API using Kubernetes and MongoDB. We’ll start by explaining the code structure of the API, followed by setting up a Kubernetes cluster with deployments and services to host the API and MongoDB. Additionally, we’ll provide YAML configurations for Kubernetes deployments and services. To help you visualize the architecture, we’ve included an architecture diagram.
The Weather Forecast API
Our Weather Forecast API is built using ASP.NET Core and MongoDB. It provides weather forecasts with temperature and summaries. Let’s dive into the code structure:
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
namespace Weather.API.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
private readonly IMongoCollection<WeatherForecast> _weatherCollection;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IMongoClient mongoClient)
{
_logger = logger;
_weatherCollection = mongoClient.GetDatabase("weather").GetCollection<WeatherForecast>("weather");
// Seed data during application startup
SeedData();
}
private void SeedData()
{
// Check if the collection exists, and if not, create it
if (!_weatherCollection.Database.ListCollectionNames().ToList().Contains("weather"))
{
_weatherCollection.Database.CreateCollection("weather");
}
// Check if the collection is empty before seeding data
if (_weatherCollection.CountDocuments(FilterDefinition<WeatherForecast>.Empty) == 0)
{
var seedData = new List<WeatherForecast>();
// Add seed data
for (int i = 0; i < 10; i++)
{
var weather = new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(i)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
};
seedData.Add(weather);
}
// Insert seed data into MongoDB
_weatherCollection.InsertMany(seedData);
}
}
[HttpGet("weather")]
public IEnumerable<WeatherForecast> Get()
{
return _weatherCollection.AsQueryable().ToList();
}
[HttpPost]
public IActionResult Post()
{
// Generate a random weather forecast
var newWeather = new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
};
// Insert the new weather forecast into MongoDB
_weatherCollection.InsertOne(newWeather);
return Ok("Weather forecast added successfully.");
}
}
}
Program.cs
using MongoDB.Driver;
namespace Weather.API
{
public static class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
string mongoConnectionString = "mongodb://mongodb-service:27017";
// Register IMongoClient in the DI container
builder.Services.AddSingleton<IMongoClient>(new MongoClient(mongoConnectionString));
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}
In this code, we initialize a MongoDB collection during controller construction and seed it with initial data. The Get
method retrieves weather data from MongoDB, and the Post
method adds new weather forecasts.
Setting up Kubernetes
Now, let’s set up a Kubernetes cluster to deploy our Weather Forecast API and MongoDB. We’ll provide the YAML configurations for deployments and services. To illustrate the architecture, here’s an architecture diagram:
Setting up Kubernetes
Now, let’s set up a Kubernetes cluster to deploy our Weather Forecast API and MongoDB. We’ll provide the YAML configurations for deployments and services.
Deployment for Weather Forecast API
apiVersion: apps/v1
kind: Deployment
metadata:
name: weather-app
spec:
replicas: 1
selector:
matchLabels:
app: weather-app
template:
metadata:
labels:
app: weather-app
spec:
containers:
- name: weather-app
image: weather-api:1.0
imagePullPolicy: Never
ports:
- containerPort: 80
env:
- name: MONGODB_CONNECTION_STRING
value: "mongodb-service:27017"
---
apiVersion: v1
kind: Service
metadata:
name: weather-app-service
spec:
selector:
app: weather-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
apiVersion
: Specifies the version of the Kubernetes API to use.kind
: Specifies the type of resource, which is a Deployment in this case.metadata
: Contains metadata for the Deployment, including its name.spec
: Defines the desired state for the Deployment.replicas
: Specifies the number of pod replicas to run. In this case, it’s set to 1, meaning one pod.selector
: Defines how to select which pods are controlled by this Deployment. It matches pods with the labelapp: weather-app
.template
: Specifies the pod template.metadata
: Contains metadata specific to pods created from this template.labels
: Assigns the labelapp: weather-app
to pods created from this template.spec
: Defines the specification for the pod.containers
: Specifies the containers to run in the pod.name
: The name of the container.image
: The Docker image to use for this container.imagePullPolicy
: Specifies the image pull policy, which is set toNever
in this case, indicating that the image should not be pulled from a registry (useful for local development).ports
: Specifies the ports to expose within the pod.env
: Defines environment variables, including theMONGODB_CONNECTION_STRING
required for connecting to MongoDB.
Deployment for MongoDB
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017
These Kubernetes configurations deploy the Weather Forecast API and MongoDB, ensuring they communicate with each other.
These Kubernetes configurations deploy the Weather Forecast API and MongoDB, ensuring they communicate with each other.
Building the Docker Image
To run the Weather Forecast API in a Kubernetes cluster, we need to build a Docker image for it. Below is the Dockerfile for the Weather Forecast API:
# Dockerfile
# Use the ASP.NET Core runtime as the base image
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
# Use the SDK image for building
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["Weather.API.csproj", "."]
RUN dotnet restore "./Weather.API.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "Weather.API.csproj" -c Release -o /app/build
# Publish the application
FROM build AS publish
RUN dotnet publish "Weather.API.csproj" -c Release -o /app/publish /p:UseAppHost=false
# Set the final base image
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Weather.API.dll"]
To build the Docker image, navigate to the directory containing the Dockerfile and run the following command:
docker build -t weather-api:1.0 .
This command builds a Docker image named weather-api
with version 1.0
. You can adjust the image name and version according to your preferences.
Deploying to Kubernetes
Now, let’s deploy the Weather Forecast API and MongoDB to your Kubernetes cluster using kubectl
commands:
Deploy the Weather Forecast API:
kubectl apply -f weather-api-deployment.yaml
Deploy MongoDB:
kubectl apply -f mongodb-deployment.yaml
Port Forwarding for Development
During development, you can access the Weather Forecast API running in your Kubernetes cluster by setting up port forwarding:
kubectl port-forward service/weather-app-service 8080:80
Now, you can access the API locally at http://localhost:8080.
Conclusion
In this blog post, we’ve covered building a Weather Forecast API using ASP.NET Core and MongoDB and deploying it in a Kubernetes cluster. Kubernetes provides scalability and high availability for your application, while MongoDB serves as a reliable data store. This setup allows you to deliver accurate weather forecasts to your users while maintaining a resilient infrastructure.
By following the provided code, Dockerfile, Kubernetes configurations, and port forwarding instructions, you can create your own weather forecast API and harness the power of container orchestration and database management with Kubernetes and MongoDB.