Page: U8 hello world
2019-12-13 20:12
U8 hello world
CLI “hello, world” app
Let’s start from writing a simple JavaScript “Hello, world” app for U8. It will be as simple as:
async function main(args) {
console.log(`Hello, ${(args.length > 0)? args[0] : 'world'}!`);
return 0;
}
You can launch it as u8 helloworld.js
, and it will print out Hello, world!
.
And if you launch it as u8 helloworld.js Yourname
(substitute your own name as the first argument),
it will print out Hello, Yourname!
.
Line-by-line explanation
async function main(args) {
The “main” function, just like in a regular application.
The args
parameter will contain the arguments passed to it during the launch.
Note the function is async!
console.log(`Hello, ${(args.length > 0)? args[0] : 'world'}!`);
U8-specific method of logging. Note the convenient ECMA 2015 backtick syntax (template literals) so you can even put some logic into your template strings.
return 0;
}
The number returned from the main async function becomes the return code of the application.
Alternatively you can return a Promise to wait on (which should provide the actual return code). You may want to read U8 main function and async calls article for more details on that.
“Hello, world” web server
Making an U8 web server is not much more complex either:
import {HttpServer} from 'web'
async function main(args) {
let httpServer = new HttpServer("0.0.0.0", 8080, platform.hardwareConcurrency);
httpServer.addRawEndpoint("/hello", async(request) => {
let nameArg = request.queryParamsMap.get("name");
let name = (typeof nameArg === "undefined")? "world" : nameArg;
request.setHeader("Content-Type", "text/html");
request.setAnswerBody(`Hello, <b>${name}</b>!`);
request.sendAnswer();
});
httpServer.startServer();
await sleep(10 * 60 * 1000);
}
Launch it as u8 helloworld_http.js
, and visit http://localhost:8080/hello
endpoint in your browser. It will return a page with “Hello, world!” words on it.
And if you pass a name
parameter to it, like http://localhost:8080/hello?name=Johnny –
the page will contain “Hello, Johnny!” (or the name you’ve passed) instead.
Line-by-line explanation
import {HttpServer} from 'web'
Some special modules (especially Universa-specific ones) are premade in the jslib
directory of U8, check GitHub (
One of them is web
, containing the HttpServer
class, supporting both raw endpoints
(for regular HTTP calls) and such Universa-specific features as “secure endpoints”.
Check out [U8 - importing and exporting symbols from JavaScript files|#151]] article for more details on importing and including the JavaScript files in U8.
async function main(args) {
A “main” function; asynchronous as usual.
let httpServer = new HttpServer("0.0.0.0", 8080, platform.hardwareConcurrency);
Create the HTTP server, using the class provided by the web
module.
The first argument is the IP to bind ("0.0.0.0"
is an usual metaphor to “bind whenever possible”);
the second argument (8080
) is the port to listen on, and the third argument
is the pool size (let’s set it to the number of the CPU cores).
httpServer.addRawEndpoint("/hello", async(request) => {
We add just a single endpoint for demo purposes, and it will be /hello
one
(note not even the /
one). You can add more endpoints yourself, if you wish.
The handler of this endpoint will be asynchronous. Async
/await
is everywhere
in U8, and this is what distinguishes it from from Node.js so much.
The handler will receive the request
argument, containing the details
of the HTTP request.
let nameArg = request.queryParamsMap.get("name");
Let’s examine the request
argument and get a name
parameter from it.
Note it can be undefined
!
let name = (typeof nameArg == "undefined")? "world" : nameArg;
We don’t want to handle the undefined
name. So if no name
argument is provided,
we will reply with the world
word; otherwise the contents of the name
argument
is used.
request.setHeader("Content-Type", "text/html");
Let’s start building a reply. The browser will treat (and format if needed) this page as the HTML page. Though there will be very little formatting.
request.setAnswerBody(`Hello, <b>${name}</b>!`);
Let’s build the reply, putting the words Hello, (and then the name or the world word)
and the exclamation sign, as usual. The name (or world
) will be HTML-formatted
in bold fonts.
request.sendAnswer();
Sending the reply back,.. and so ends the endpoint handler.
});
… and so ends the endpoint (/hello
) handler.
httpServer.startServer();
We’ve prepared our HTTP server and made a single endpoint handler. Now just launch it.
await sleep(10 * 60 * 1000);
}
Interestingly, if we just return from here – our main function will be finished, so the application is closed immediately. And our web server we’ve spent so much time to built, quits immediately too.
So we need to pause somehow. We can “await forever”, have a Promise
-returning
function which decides when the web server (and the application) should quit;
in this example, we just await
for 10 minutes and then exit.
This ends our tiny but fully functional web server.