import*ascorsfrom'cors';import*asexpressfrom'express';importgotfrom'got';constbaseUrl='https://atlas.microsoft.com/weather/';constbaseQuery=`api-version=1.0&subscription-key=${process.env['SubscriptionKey']}&unit=imperial`;constapp=express();app.get('/weather/:lat,:lon',cors(),async(req,res,next)=>{try{constlat=parseFloat(req.params.lat);constlon=parseFloat(req.params.lon);constcurrentQuery=got(`${baseUrl}currentConditions/json?${baseQuery}&query=${lat},${lon}`);consthourlyQuery=got(`${baseUrl}forecast/hourly/json?${baseQuery}&query=${lat},${lon}&duration=24`);constdailyQuery=got(`${baseUrl}forecast/daily/json?${baseQuery}&query=${lat},${lon}&duration=10`);// Wait for the 3 parallel requests to complete and combine the responses.const[currentResponse,hourlyResponse,dailyResponse]=awaitPromise.all([currentQuery,hourlyQuery,dailyQuery]);awaitres.json({currentWeather: JSON.parse(currentResponse.body).results[0],hourlyForecasts: JSON.parse(hourlyResponse.body).forecasts,dailyForecasts: JSON.parse(dailyResponse.body).forecasts,});}catch(err){// Express doesn't handle async errors natively yet.next(err);}});constport=process.env.PORT||3000;app.listen(port,function(){console.log(`Listening on port ${port}`);});
using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Hosting;using Microsoft.AspNetCore.HttpsPolicy;using Microsoft.AspNetCore.Mvc;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using Microsoft.Extensions.Logging;using Microsoft.OpenApi.Models;namespaceWebApiWeather{publicclassStartup{publicStartup(IConfigurationconfiguration){Configuration=configuration;}publicIConfigurationConfiguration{get;}// This method gets called by the runtime. Use this method to add services to the container.publicvoidConfigureServices(IServiceCollectionservices){
services.AddControllers();
services.AddHttpClient("weather",options =>{ options.BaseAddress =new Uri("https://atlas.microsoft.com/weather/");});
services.AddCors(options =>{ options.AddPolicy("weather",policyBuilder => policyBuilder.AllowAnyOrigin());});
services.AddSwaggerGen(c =>{ c.SwaggerDoc("v1",new OpenApiInfo {Title="WebApiWeather",Version="v1"});});}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){if(env.IsDevelopment()){
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json","WebApiWeather v1"));}
app.UseRouting();
app.UseCors();
app.UseHttpsRedirection();
app.UseEndpoints(endpoints =>{ endpoints.MapControllers();});}}}
using System.Net.Http;using System.Net.Http.Json;using System.Threading.Tasks;using Microsoft.AspNetCore.Cors;using Microsoft.AspNetCore.Mvc;using Microsoft.Extensions.Configuration;namespace WebApiWeather.Controllers
{[ApiController][Route("[controller]")]publicclassWeatherController:ControllerBase{privatereadonlyHttpClient_httpClient;privatereadonlystring_baseQuery;publicWeatherController(IHttpClientFactoryclientFactory,IConfigurationconfig){_httpClient= clientFactory.CreateClient("weather");_baseQuery=$"api-version=1.0&subscription-key={config["SubscriptionKey"]}&unit=imperial";}[EnableCors("weather")][HttpGet("{latitude},{longitude}")]publicasyncTask<CombinedWeather>Get(doublelatitude,doublelongitude){varcurrentQuery=GetAsync<CurrentWeather>("currentConditions/json",$"&query={latitude},{longitude}");varhourlyQuery=GetAsync<HourlyForecast>("forecast/hourly/json",$"&query={latitude},{longitude}&duration=24");vardailyQuery=GetAsync<DailyForecast>("forecast/daily/json",$"&query={latitude},{longitude}&duration=10");// Wait for the 3 parallel requests to complete and combine the responses.await Task.WhenAll(currentQuery, hourlyQuery, dailyQuery);returnnew(){CurrentWeather= currentQuery.Result.Results[0],HourlyForecasts= hourlyQuery.Result.Forecasts,DailyForecasts= dailyQuery.Result.Forecasts,};}privateTask<T>GetAsync<T>(stringpath,stringquery)=> _httpClient.GetFromJsonAsync<T>($"{path}?{_baseQuery}{query}");}}