ASP.NET Web API/React SPA - reactjs

I have followed exactly (multiple times) the .NET tutorial on creating a Weather Forecast API/SPA pair and the two are not able to communicate. Here is the error, which is reported in the console log of the React SPA:
Failed to load resource: the server responded with a status of 504
(Gateway Timeout) :3000/weatherforecast:1
I do not fully understand proxies but my understanding is that if the ports match, the process of sending data from the API to the SPA should work. Here are my current settings with respect to ports:
launchSettings.JSON (API)
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:8772",
"sslPort": 44311
}
},
"profiles": {
"API": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:7036;http://localhost:5036",
"dotnetRunMessages": true
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
setupProxy.js (React SPA)
const { createProxyMiddleware } = require('http-proxy-middleware');
const context = [
"/weatherforecast",
];
module.exports = function (app) {
const appProxy = createProxyMiddleware(context, {
target: 'https://localhost:8772',
secure: false
});
app.use(appProxy);
};
My understanding is that these two applications should be able to communicate because they have a common port of 8772, but I suppose my assumption must be wrong? Thanks for your support.

Related

NextJS build command hangs indefinitely on our server

I'm having a problem when running next build on my local machine (Windows 10) the command builds the app successfully
But when doing so on my server (running on linux 4.18.0-372.9.1.1.lve.el8.x86_64 the build hangs indefinitely, this was tested on my current project, I've also tried testing on a new project created on the linux server and got the same issue
I tried skipping linting and type checks from next.config.js but it still hangs
I noticed this process running while the app is "building", might be the source of the issue but I'm not sure
I might also be missing some dependencies that I am not aware of, any ideas?
Edit (1)
// next.config.js
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
distDir: "./build",
images: {
remotePatterns: [
{
protocol: "http",
hostname: "localhost",
port: "1337",
pathname: "/uploads/**",
},
{
protocol: "http",
hostname: "127.0.0.1",
port: "1337",
pathname: "/uploads/**",
},
],
},
async redirects() {
return [
{
source: "/news",
destination: "/",
permanent: false,
},
];
},
};
const withBundleAnalyzer = require("#next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
module.exports = withBundleAnalyzer(nextConfig);
Edit (2)
While the app is building, the cpu usage shoots between 92% and 100%, without building it rests at 14%
Is there a way to bypass running tests with jest while building?

Nx advanced reverse proxy configuration

Migrating a react application to an Nx integrated workspace, and having an issue with advanced proxy configuration.
I understand that for a simple proxy...
Specify the proxy.conf.json file
"serve": {
"executor": "#nrwl/webpack:dev-server",
"defaultConfiguration": "development",
"options": {
"verbose": true,
"buildTarget": "ydsca:build",
"hmr": true,
**"proxyConfig": "apps/ydsca/proxy.conf.json",**
"ssl": true,
"sslKey": "certs/localhost.key.pem",
"sslCert": "certs/localhost.crt.pem"
},
Implement the proxy.conf.json file, e.g....
{
"/caconnect/common/*": {
"target": "https://127.0.0.1:9443",
"secure": false,
"logLevel": "debug"
}
}
This works without any issues, however, the current React application uses "http-proxy-middleware" and a more advanced setupProxy.js file (wildcard matching such as "/**/common/" for any patch that contains /common/):
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
[
'/**/common/',
'/**/commonClassic/',
'/**/ydscaCommon/',
'/ymca',
'/staff'
],
createProxyMiddleware({
//Must use 127.0.0.1 as for some reason, localhost stopped working in node versions > 16
target: 'https://127.0.0.1:9443',
//Necessary for https with self signed certificates
secure: false,
changeOrigin: false,
//Additional logging stuff!
onProxyReq: function onProxyReq(proxyReq, req, res) {
// Log outbound request to remote target
console.log('--> ', req.method, req.path, '->', proxyReq.baseUrl + proxyReq.path);
},
onError: function onError(err, req, res) {
console.error(err);
res.status(500);
res.json({error: 'Error when connecting to remote server.'});
},
//logLevel: 'debug'
})
);
};
How can the same advanced proxying be configured in Nx?
Tried changing proxyConfig": "apps/ydsca/proxy.conf.json" to proxyConfig": "apps/ydsca/setupProxy.js", but it doesn't seem to like javascript files for proxy configuration!
Any suggestions?
Thank you.

Webpack 5 module federation error handling

I've a micro frontends running on monorepo using nx CLI where in the host application I'm using module federation to get the remoteEntry.js files from all the micro frontends and serve them as components per route.
I've error boundary which works perfect on dev / staging / production environment and displays 404 page when the remoteEntry is not fetched / crashed for some reason and it works as expected.
But when I want to run unit tests on the shell application to test its functionality and I'm running only the shell application, for some reason I'm receiving errors from webpack saying the following:
Loading script failed.
(error: http://localhost:3107/remoteEntry.js)
Which is expected, because I didn't run any of the micro frontends.
What I want to achieve is that I will be able to run only the shell application locally and get the 404 page also on local without having this error, in other words - I want to handle the errors when the micro frontends are not live.
Any suggestions how can I achieve that?
webpack file on the shell application:
const nrwlConfig = require('#nrwl/react/plugins/webpack.js');
const { ModuleFederationPlugin } = require('webpack').container;
const deps = require('../../package.json').dependencies;
const { remoteEntries } = require('./remoteEntries');
const EnvType = {
LOCAL: 'local',
PLAYGROUND: 'playground',
DEVELOPMENT: 'development',
STAGING: 'staging',
PRODUCTION: 'production',
};
module.exports = (config) => {
nrwlConfig(config);
config.optimization.runtimeChunk = 'single';
return {
...config,
plugins: [
...config.plugins,
new ModuleFederationPlugin({
name: 'hostApp',
filename: 'remoteEntry.js',
remotes: {
app1: `app1#${getRemoteEntryUrl(remoteEntries.APP1)}`,
app2: `app2#${getRemoteEntryUrl(remoteEntries.APP2)}`,
app3: `app3#${getRemoteEntryUrl(
remoteEntries.APP3
)}`,
app4: `app4#${getRemoteEntryUrl(
remoteEntries.APP4
)}`,
app5: `app5#${getRemoteEntryUrl(remoteEntries.APP5)}`,
app6: `app6#${getRemoteEntryUrl(
remoteEntries.APP6
)}`,
app7: `app7#${getRemoteEntryUrl(
remoteEntries.APP7
)}`,
},
shared: {
...deps,
react: {
singleton: true,
eager: true,
requiredVersion: deps.react,
},
'react-dom': {
singleton: true,
eager: true,
requiredVersion: deps['react-dom'],
},
},
}),
],
};
};
const getRemoteEntryUrl = (entry) => {
const { NODE_ENV } = process.env || EnvType.DEVELOPMENT;
if (NODE_ENV !== EnvType.LOCAL) {
return entry.remoteEntries[NODE_ENV];
}
return `http://localhost:${entry.localPort}/remoteEntry.js`;
};

Trouble connecting to SQL Server with Cypress

Having an issue with where i seem to be connecting to SQL Server but cannot find the server/db.
I have been trying to follow the steps in this guide for Cypress 9 but to no avail.
https://www.npmjs.com/package/cypress-sql-server
There was an answer on SO that i've been trying to use but I can't reply to a comment and add a comment but it was deleted by the mods for some reason. This is the URL to the answer I have been trying to follow but can't connect.
How to configure cypress-sql-server with no cypress.json? (updated)
Has someone please got a working example?
cypress.config.ts
const { defineConfig } = require("cypress");
const sqlServer = require("cypress-sql-server");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// allows db data to be accessed in tests
config.db = {
"userName": "x",
"password": "x",
"server": "xxx\\SQLEXPRESS",
"options": {
"database": "xxxxxx",
"encrypt": true,
"rowCollectionOnRequestCompletion": true,
"trusted_connection": true
}
}
// code from /plugins/index.js
const tasks = sqlServer.loadDBPlugin(config.db);
on('task', tasks);
return config
// implement node event listeners here
},
},
});
export default defineConfig({
chromeWebSecurity: false,
videosFolder: 'cypress/videos',
screenshotsFolder: 'cypress/screenshots',
fixturesFolder: 'cypress/fixtures',
video: false,
reporter: 'cypress-mochawesome-reporter',
reporterOptions: {
reportDir: 'cypress/reports',
charts: true,
reportPageTitle: 'xxxxxxxx',
embeddedScreenshots: true,
inlineAssets: true,
},
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.ts')(on, config)
},
experimentalSessionAndOrigin: true,
specPattern: 'cypress/e2e/tests/orders/*',
baseUrl: 'http://localhost:4200',
},
})
index.ts
const { defineConfig } = require('cypress')
module.exports = (on, config) => {
require('#cypress/code-coverage/task')(on, config);
require('cypress-mochawesome-reporter/plugin')(on);
return config;
}
e2e.ts
import '#cypress/code-coverage/support';
import './commands';
import 'cypress-mochawesome-reporter/register';
import sqlServer from 'cypress-sql-server';
sqlServer.loadDBCommands();
}
Tried creating a new sysadmin also on SQL Server in case it was an access issue
The TCP/IP Properties for your instance should look like this to make it listen on port 1433: On IPALL clear the TCP Dynamic Ports and set TCP Port to 1433.
You have the pattern for cypress.config.js plus the one for cypress.config.ts in your config file, but it's either/or not both at once.
See example Configuration.
Since you use typescript, try
import { defineConfig } from 'cypress'
import sqlServer from 'cypress-sql-server'
const dbSettings = {
"userName": "x",
"password": "x",
"server": "xxx\\SQLEXPRESS",
"options": {
"database": "xxxxxx",
"encrypt": true,
"rowCollectionOnRequestCompletion": true,
"trusted_connection": true
}
}
export default defineConfig({
chromeWebSecurity: false,
... // other cofinfig settings
e2e: {
setupNodeEvents(on, config) {
config.db = dbSettings;
const tasks = sqlServer.loadDBPlugin(dbSettings);
on('task', tasks);
return require('./cypress/plugins/index.ts')(on, config)
},
experimentalSessionAndOrigin: true,
specPattern: 'cypress/e2e/tests/orders/*',
baseUrl: 'http://localhost:4200',
},
})

How do I solve CORS Policy error with .NET 6 and React?

I am trying to call an API in the frontend, but I get this error instead:
Access to XMLHttpRequest at 'http://localhost:5087/api/GetPlayerById/2' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Frontend is running on http://localhost:3000/ (React)
Backend is running on http://localhost:5087/ (.NET 6)
API works on Postman
API works on browser (Copy/Pasting the API on browser)
CORS error appears when I call the API in React
I already looked at many post on CORS policy but none seems to help me. My last attemp was referring to Enable Cross-Origin Requests (CORS) in ASP.NET Core.
Code so far (in .NET 6):
Program.cs
using tournament_manager_backend.Data;
using Microsoft.EntityFrameworkCore;
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("http://localhost:3000");
});
});
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"));
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddScoped<IPlayerRepository, PlayerRepository>();
builder.Services.AddScoped<IMatchRepository, MatchRepository>();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();
app.MapControllers();
app.Run();
appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "server=(localdb)\\ProjectModels;database=TournamentManager"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Host": {
"CORS": "http://localhost:5087,http://localhost:3000"
}
}
launchSettings.json
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:19870",
"sslPort": 44328
}
},
"profiles": {
"tournament_manager_backend": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5087",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
}
}
}
}
I know there are a lot of questions on this topic already but I have already changed the code many times from different sources that if I were to refer them here, it will make this post too long. I did the best I can to give you as much details as possible so that I can seek effective guidance. I will appreciate anyone helping. Thanks!
The easiest solution is to include a proxy in the React server that you're using for development. In your package.json include:
"proxy": "http://localhost:5087/",
as part of the top level parameters (i.e., no parent). This creates a proxy through http://localhost:3000/ to your back end.
Note that this is for development. When you move to a "real" server you won't be using the React dev server for serving your front end code and there will likely be a different way to setup CORS.

Resources