Our main backend server is a .net 5 web API project. I'm needing to integrate some javascript modules and javascript code into our functionality. I'm wanting to save on the time of rewriting these modules all into c# to access from our code. Are there any packages or methods to accomplish this or am I best of running a separate node server for this functionality?
Option 1. Access A Node.js Server Script From C#/.Net 5
Jering.Javascript.NodeJS enables you to invoke javascript in a Node.js module from C#. With this ability, you can use Node.js scripts/modules from within your C# projects. Supports: Callbacks, Promises and Async/Await. Get js scripts via file path, string or stream. You can run a single global instance of your Node.js App that remains in memory or create a new instance for each call. See an example on Invoking Javascript From File.
Install Via Package Manager or .Net CLI
Install-Package Jering.Javascript.NodeJS
#or
dotnet add package Jering.Javascript.NodeJS
some-module.js
module.exports = {
doSomething: (callback, message) => callback(null, { message: message + '!' }),
doSomethingElse: (callback, message) => callback(null, { message: message + '.' })
}
In your .Net App
var services = new ServiceCollection();
services.AddNodeJS();
ServiceProvider serviceProvider = services.BuildServiceProvider();
INodeJSService nodeJSService = serviceProvider.GetRequiredService<INodeJSService>();
public class Result {
public string? Message { get; set; }
}
Result? result = await nodeJSService.InvokeFromFileAsync<Result>("some-module.js", "doSomething", args: new[] { "success" });
Assert.Equal("success!", result?.Message);
This is a basic implementation example. You should see the Jering.Javascript.NodeJS Docs for complete examples of installation, configuration and usage.
Option 2. HTTP REST / Web Socket
Create an HTTP Rest or WebSocket Wrapper around your JS scripts and call them from the .Net App. In your .Net App, use HttpClient class to make HTTP requests. Then over in Node.js wrap your scripts with routes to access various methods. Something like:
const express = require('express');
const app = express();
const port = 3000;
app.get('/some/endpoint', (req, res) => {
// Gets executed when the URL http://localhost:3000/some/endpoint
// Do your thing here
// Return it back to .Net with:
res.send(JSON.stringify({some_response: "Hello There"}))
});
// Start the http server
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
});
Using the HTTP Rest/WebSocket option will require that you already have your node.js app running (and keep it running) before you attempt to call the endpoints from .Net.
Option 3. Execute Standard Javascript Embedded Scripts
Here are the most popular .Net modules that will allow you to run Standard Javascript code within your C# .Net Service. However, these both execute your JS Scripts using the V8 Engine and will not work for Node.js specific methods such as FileSystem. These will also not allow the use of require() or Import. This might be a good option if you have very limited Javascript needs and will not be adding additional JS functions in the future.
Microsoft.ClearScript
Jint
Javascript.Net
This option is quick and simple for very small scripts, but would be the most difficult to update and maintain your JS scripts.
Related
Here is my HTML code in index.html.
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="stuff()">Click</button>
<script>
async function stuff() {
await connectToServer();
}
async function connectToServer() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
alert(this.responseText);
};
xhttp.open('GET', 'C:/Users/myName/myFolder/index.js', true);
xhttp.send();
return;
}
</script>
</body>
</html>
Then, here is my backend code in index.js.
const express = require('express');
const axios = require('axios');
const port = process.env.PORT || 8080;
const app = express();
app.get('/', (req, res) => {
res.sendFile('C:/Users/myName/myFolder/views/index.html');
});
app.listen(port, () => console.log(`Listening on port ${port}`));
I can type node index.js on the command line and run this program and go to http://localhost:8080/ . When I do this, the html page shows up as intended. However, when I click the button in order to make a GET request to the server side, I get a console error saying Not allowed to load local resource: file:///C:/Users/myName/myFolder/index.js . I'm using Google Chrome by the way.
I know that it is a security thing, and that you are supposed to make requests to files that are on a web server (they begin with http or https). I suppose then, my question is:
How do I make it so that my server file index.js can be viewed as being on a server so that I can call functions on the backend from my frontend?
You have to make an HTTP request to a URL provided by the server.
The only URL your server provides is http://localhost:8080/ (because you are running an HTTP server on localhost, have configured it to run on port 8080, and have app.get('/', ...) providing the only path.
If you want to support other URLs, then register them in a similar way and write a route to handle them.
The express documentation will probably be useful.
You should not need to load your server-side code into the browser. It's server-side code. It runs on the server. It isn't client-side code. It doesn't run in the browser. The browser does not need access to it.
If you want to load some actual client-side JS from the server, then use <script src="url/to/js"></script> (and not Ajax) and configure express' static middleware.
Let's improve your current flow by separating your backend API process from frontend hosting process. While backend can, it's not good in serving static html files (especially for local development purposes).
Run your backend as usual, node index.js. But as soon as this command will become more complicated, you will probably want to use npm scripts and do just npm start)
Run separate server process for frontend. Check out parcel, snowpack, DevServer. It can be as easy as npx parcel index.html, but this command is likely to change frequently with your understanding of your tool features.
To call backend, just add an API endpoint to an express app (just like you already did for serving static content), and call it, using backend process URL.
Usually, you will see your app on http://localhost/ and it should do requests to http://localhost:8080/.
If for some strange reason you will want to dynamically download js file from your server to execute it, you just need to serve this file from your frontend hosting process. In order to do so, different development servers have different techniques, but usually you just specify file extensions and paths you want to be available.
After editing frontend files, you will see hot-reload in browser. You can achieve the same for node process with various tools (start googling from nodemon)
If you find this way of operating not ideal, try to improve it, and check what people already did in this direction. For example, you can run two processes in parallel with concurrently.
I am new to js and I am trying to develop a simple node.js-mysql app. No matter what I do I can't get the standard
var express = require("express");
statement to work.
I have installed node.js and express correctly, express is in package.json. I have a local server running. But this simple line will not work.
On the node.js side at Windows command line I have no error but when I go to localhost:3000 on the browser, I get
'Uncaught Error: Module name "express" has not been loaded yet for
context: _. Use require([])' error at js console.
I tried changing it to
require(['express']`, function (express) {}
as suggested at node.js web site but then at the Windows command terminal I get a different error saying like
'expecting a string but received an array....'.
I have tried import instead of require and I have tried every suggestion that I could find on the Internet. I have been blowing my brains for weeks to get this to work with no success. I am so frustrated that I am seriously thinking about giving up all together. If someone can help I will be forever greatfull to him/her.
My main js code is as follows:
var port = 3000;
// Import or load node.js dependency modules.
var express = require("express");
var app = express();
var path = require("path");
var bodyParser = require("body-parser");
app.use(express.urlencoded({ extended: true })); // to support URL-encoded bodies.
app.listen(port, () => {
console.log(`server is running at http://127.0.0.1:8887`);
});
app.get('/', function(req, res){
res.sendFile("D:/Behran's files/Web projects/havuzlusite/index.html");
});
Require.JS is for loading AMD modules (and is, honestly, obsolete in today's JS landscape).
Node.js modules are either ECMAScript modules (which use import and export) or CommonJS modules (which use require and module.exports).
Even though both AMD and CommonJS modules use a function named require they are not compatible.
There are methods you can use to run ES modules and CommonJS modules in the browser however they can't replace APIs that are provided by runtimes.
Express.js needs to be able to listen for incoming HTTP requests. Browsers do not provide any mechanism to make that possible. Node.js does.
If you want to run Express.js you have to run it using Node.js and not a browser.
Express.js creates an HTTP server. A browser can make requests to it (e.g. if you type http://127.0.0.1:3000 into the address bar.
(Your code says server is running at http://127.0.0.1:8887 but the port constant is set to 3000).
All your Express.js code must run through Node.js.
You can't send a copy of that code to the browser and run it there too.
Hello I need to run a function on first start of the server, basically I want to put some constant data in the database. Yes, I could use just a in memory constant for this but I'd rather have it in my database because I am planning on using that data on some of my other servers in the future. The problem is, I am using NextJS and I want to host on the Vercel platform so I don't want to use a custom server.js file.
Is there any way to run a function only once when the server first starts in NextJS/NodeJS?
So the Vercel platform is serverless: https://vercel.com/docs/serverless-functions/introduction.
As it states in the documentation you can create a serverless function like so:
module.exports = (req, res) => {
res.send("Hello World");
}
If you wish to run a function after the build is done you can look at this answer:
Next.js run function/script when starting app
You could also use getServerSideProps to run code before the page renders (on the server side) if that is what you mean with "app start".
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
My goal is this: JS but server-side. My solution, the obvious, node.js. I've used node.js quiet a bit. Mainly for an application, not a web server. The only reason I need to do server-side JS is that I need to use a library that connects to the Discord API. So I have a little test .js file with my node.js in it. It just prints text if it works. Basic. What I need it to do is whenever someone goes to https://example.com/something, it runs the node.js script and if the script ends up with printing "hello", then https://example.com/something will say "hello".
I've done some research on this, I've found ways to deploy a node.js app, which I know how to do. I can't really find anything that I'm looking for though.
You can use express to run a webserver on nodejs
Install express by running "npm install express" in your project folder through command prompt
Create a app.js file with the following code
var express = require('express'); // load the express library
var app = express(); // create an instance of express
var child_process = require('child_process'); //load the child_process module
app.get("/something", function(req, res) { // Setup a router which listens to the site http://localhost/something
child_process.fork("./yourCodeFile.js"); // Launch your code file
});
app.listen(80);
Run node app.js to listen to web connections
Then you put your code into the yourCodeFile.js which has to be be in the same folder as the app.js file, even better you could just write all your code in the app.js code as long as you keep it inside the function inside app.get
You should take a look at cloud-based lambda functions and platforms like AWS Lambda, which run a script in response to an HTTP request. They are relatively new and the architecture used to support this is being called "serverless", which is a simple term, albeit a bit of a misnomer. There are various tools out there to help you build these systems, such as the similarly named Serverless framework, though you can typically still use more traditional server frameworks that you are probably more comfortable with. Either way, you are not responsible for managing any server, including starting it or stopping it.
In terms of constructing a response that you are happy with, you can of course respond with any arbitrary string you want. See the AWS example of a Node.js handler.
exports.myHandler = function(event, context, callback) {
callback(null, "Hello, world!");
}
Lambda functions can also return binary data and work well with static storage systems like Amazon S3. For example, the function can be run in response to the creation of static assets.
Your code should look like this:
const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
const pathName =url.parse(req.url).pathname;
if (pathName == '/something') {
res.end('Hello World\n');
} else {
res.end('Please visit /something \n');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
You should run your file with node youfile.js And when you do curl http://127.0.0.1:3000 you will see
Please visit /something
But when you do curl http://127.0.0.1:3000/something you will see
Hello World
I am going to learn Node.js and right now I was trying to make a small demo project which implements an HTTP REST service.
My idea is to divide the APIs (url) by Resources and end up in a structure like the following one:
- user
> index.js
> post.js
> put.js
> delete.js
> functions.js
- person
> index.js
- index.js
So, if you are familiar with ASP.NET Web Api, I am trying to make every module of Node.js a Controller and every web method a single file (.js), in order to have an high maintainability in the future.
Question
Right now, my index.js file return the following:
var http = require('http');
var server = http.createServer();
How can I configure a specific "Request Handler" in each file by using this module? At the moment the createServer() method return a server object can use a single server.on('request', function) while I need to handle each request in a different file.
Go ahead learning with the help of some framework. They provide scaffolding of project.
If you are developing a complete web app(MVC) then go for ExpressJs or SailsJs
If you are looking out to develop only API(No Views) then go for Strongloop or Restify
There are many more frameworks but the above ones are popular.