Achieve Node.js Server with JavaScript Servlets
Achieve is a modern (http, https, http2) web server that runs on Node.js and uses JavaScript Servlets to initiate back end processing. (npm, github) JS Servlets are fast, very easy to use, and do not limit your ability to develop sophisticated back end applications; perfect for rapid development of microservices or complete Node.js based web applications. You can even use it just to serve web pages.
Some Servlet features: The servlet container handles text responses. You simply send a result back using a return statement in the servlet. When you change your back end programs, they are automatically reloaded. No need to restart the server every time you make a change. If there is an error in your application code, you receive a very informative error message - without crashing the server. When using XHR, error messages can be displayed in the browser's inspector-console just as errors in browser code do.
You can also take control of the response via the Servlet Session to, for example, set headers and return blobs.
Achieve is easy to install and run. No dependencies. Requires Node.js v8.1 or later. (Developed / tested with v8.9.4)
This is a quick-start guide. If you need more help getting started, from using localhost and local IP addresses to obtaining security certificates and forwarding ports, click here.
From beginners:
- You do not need to know anything about Node.js.
- You can Achieve as you are learning JavaScript.
- You can write back end apps without knowing HTML or CSS.
- Recommended for use in early web development training.
- Recommended for use while learning JavaScript.
- Recommended for early training in other web related technologies such as database.
To advanced users:
- Excellent development features.
- Fast enough for production.
- Take control through use of the Servlet Session.
- Apply advanced JavaScript and Node.js knowledge.
- Use other Node.js modules in your applications.
Regular HTTP/S features:
- Delivers static content.
- Unlimited MIME support.
- Runs back-end JavaScript programs (via JavaScript Servlets).
- Supports defaults index.html, index.htm, index.js
- Supports browser caching. (ETag)
- Supports compression with ss caching. (gzip,deflate)
- Streaming audio/video files.
Special Features:
- No knowledge of Node.js required to start using JS Servlets.
- Little knowledge of JavaScript required to start using JS Servlets.
- Servlets handle HTTP/S Response. App just uses return statement.
- Useful app error reports can be displayed in browser console.
- Automatic reload of modified files.
- Servlet Session Object allows developer to take complete control.
- Node.js environment configuration. (development,production)
- Configurable apps folder path and path to the ROOT application.
Quick Start Tutorial
First: Install Node.js (LTS recommended), version 8.1 or later.
Running Achieve (simplest form):
const server = require('achieve');
server.listen(); // defaults to port 80 .. change it to something else if you wish
Copy the code above and save it to a directory that will serve as the root for your applications. You can call the file server1.js. If you need to use a port other than 80, include the port number as an argument to the listen() method. (exp: server.listen(8989);)
Open a command window (cmd) and cd into your application directory (where the code above is saved). On the command line, type the following:
npm install achieve
At the end of npm's actions and commentaries, you should get something like this:
+achieve@1.0.5
added 1 package in 7.281s
Start the server:
Type "node server1
" (assuming you named the file server1.js).
You should get a response:
You are ready to serve static content. (html, css, javascript for browser) We will do that in a minute. Let's start instead with a simple example of a JavaScript Servlet.
Hello World Servlet:
// Save this code in file index.js in the apps directory ("application base" - directory where you are running the server)
exports.servlet = function (session) {
return "Hello World!"; // Achieve handles the response.
}
In your browser's address bar, enter http://localhost:8989 (assuming port 8989). The text "Hello World!" should appear. Now, without restarting the server; change the text in your servlet to, for example; "Hello There World!" Refresh the page. Achieve will detect a change and reload the file. Servlet caching works pretty much the same way browser caching works. The cached version will be used as long as the file hasn't been changed.
When the file name is not given in the URL, Achieve searches for index.html, index.htm, and index.js; in that order. If it uses index.js, it will run the servlet on the server and return the result. You can achieve the same result by giving the name of any JavaScript Servlet file without the .js extension. In this case: http://localhost:8989/index Including the .js extension corresponds to a browser's request for a resource. http://localhost:8989/index.js will serve the file instead of running it.
Achieve will also return helpful error messages to your browser's console. First, let's receive an error message to
the page. Modify your servlet to cause an error by deleting a few characters from the end of the return statement:
return "Hello World
. Refresh the page.
To see how to receive error message in the browser's console, save this
HTML file and save it to your apps directory as index.htm. (Note that it presumes that your servlet file name is index.js)
Open the inspector in your browser and click on the console tab. Then
reload http://localhost:8989 On the browser side, the trick is in the callback() function. If the response status is not 200:
console.error(this.responseText);
This is a feature
supported by Achieve. Note also that the URL specified in function runServlet() is "index", without the .js extension.
Access parameter values that were sent with the request:
var myParm = session.parms.myParm; // or
var myParm = session.parms['myParm'];
Running Achieve with options:
const server = require('achieve');
server.setAppPath("c:/myachieve/myapps"); // set root directory for all applications
server.setRootDir('root'); // set a subdirectory under the root directory for THE ROOT application
server.setCaching(true); // turn browser caching support on
server.setCompress(true); // compress static resources
server.showMimeTypes(); // Show the current list of supported Mime Types
server.addMimeType("pub","application/x-mspublisher"); // add an unsupported MIME type
server.addAVMimeType("wav","audio/wav"); // add an unsupported AV MIME type
server.setNodeEnv("development"); // set Node environment
server.listen(8989); // listens on port 8989
Servlets can use other functions:
exports.servlet = function (session) {
return hello();
}
function hello () {
return "Hello World!";
}
Servlets can use functions in other files.
// in otherfile.js
exports.hello () {
Return "Hello World!";
}
// in myservlet.js
exports.servlet = function (session) {
var other = session.load("otherfile.js"); // Extends servlet features to otherfile; reloads if cache is stale.
return other.hello();
}
The Servlet Session
You can use the Servlet Session to take control of your back end process. The Servlet Session contains:
session.request // The session request object.
session.response // The session response object.
session.parms // Parameters sent with the request
session.dirPath // The current application path on your computer
session.load // The JavaScript Servlet load() method (see above)
session.allowAsync // Set to true if you handle the response in an asynchronous process.
Achieve HTTPS:
Using HTTPS on Achieve is actually quite simple. It shares configuration set-ups with Achieve HTTP. The difference is in the listen methods. Achieve HTTPS has its own, called slisten(). slisten() requires a JSObject as input, which lists your security certificates. Security certificates, and how to obtain them (cost free) is explained on the help page.
Running Achieve HTTPS (simplest form):
const server = require('achieve');
const fs = require('fs');
const options = { // An easy way to acquire free certificates is explained in the beginner's tutorial.
key: fs.readFileSync('C:/certs/private.key'), // For certificate files that have been placed in C:/certs/
ca: fs.readFileSync('C:/certs/bundle.crt'), // optional, provides "full chain" of certificates
cert: fs.readFileSync('C:/certs/certificate.crt')
};
server.slisten(options);
Port 443 is the default port for HTTPS. If you need to use a different port, add the port number
to the options object.
const options = {
key: fs.readFileSync('C:/certs/private.key'),
ca: fs.readFileSync('C:/certs/bundle.crt'), // optional
cert: fs.readFileSync('C:/certs/certificate.crt'),
httpsPort: 7777
};
Achieve HTTP2:
Using HTTP2 on Achieve is also easy. It shares configuration set-ups with Achieve HTTP/S. It also has its own listen method - listen2(). You may use HTTP2 without encryption and without security certificates. Simply follow instructions for HTTP above, but using .listen2() rather than .listen(). Note however that browsers are not accepting unencrypted traffic on HTTP2. If your target client is a web browser, or if you need secure connections with other clients, follow the instructions for HTTPS above (using .listen2()), but with the port property name http2Port. Achieve HTTP2 requires Node.js v10.16.0 or higher.
TO DO List
- Error handling - f.ex. custom 404 page.
- Support 3rd party logging modules (developer's choice).
- Test HEAD method.
- Netbeans support?
- CORS support?
Future
- Integrate HLL Websockets.
- Complete and integrate HLL intelligent application framework.