Hello World!
Learning objectives
- You can create and run a web server using Deno.
Hello world!
We start with creating an application that outputs the message Hello world!
. In this case, however, the message is not printed to the console or command line, but shown in the browser.
Create a file called app.js
and copy-paste the following content to the file.
Deno.serve(() => new Response("Hello world!"));
Save the file and go to the file using the terminal. In the directory that contains the file, type in the command deno run --allow-net --watch app.js
. This will run the program. On the command line, this will look like follows (in the below example, the command ls
is used to list files in the current directory).
ls
app.js
deno run --allow-net --watch app.js
Watcher Process started.
Listening on http://localhost:8000/
Now, open up your browser and go to the address http://localhost:8000. You should see the text Hello world!
shown in the browser. Try out the application also on the command line using the curl
command. Open a separate terminal and write the command curl http://localhost:8000
and then press enter. This will print the response from the server to the terminal window.
curl http://localhost:8000
Hello world!
Starting and stopping the server
The command deno run --allow-net --watch app.js
runs the code in the file app.js
and starts the server. To stop the server, press Ctrl + C
on the keyboard. If you do not stop the server and try to run the command again, you will get an error message stating that the port is already in use.
Disentangling the run command
The run command that we used above consists of a few parts. The first part is deno run
. This part tells Deno to run the code in the file that is given as a parameter. The second part is --allow-net
. This part tells Deno to allow the program to access the network. The third part is --watch
. This part tells Deno to watch for changes in the file and restart the program when the file is changed. The final part -- app.js
-- is the name of the file that should be run.
The flag
--watch
is not always needed, but it is very useful when developing applications. Using it will automatically restart the server when the file is changed. Try changing the code to something else, saving the file, and refreshing the browser window.
Breakdown
Let's look at the application that we just tried out. The code was as follows.
Deno.serve(() => new Response("Hello world!"));
In the above program, we create a function that returns a new Response object. The constructor for Response
is given the string "Hello world!" as a parameter. The function is then given as a parameter to the function Deno.serve
, which creates a server that starts to listen for requests, handling them with the given function.
Documentation for
Deno.serve
is available at https://deno.land/api?s=Deno.serve.
The application can be decomposed into two parts, where we first define the function, and then pass the function to the Deno.serve
function. The following program is equivalent to the one above.
const handleRequest = () => {
return new Response("Hello world!");
};
Deno.serve(handleRequest);
Brief notes about Deno
Deno is a secure runtime for JavaScript and TypeScript.
Security in Deno refers to the runtime having disabled access to files, network, etc, by default. If access to such services is needed, we will have to explicitly grant it when launching the program. For example, running the previously seen Hello world!
application will ask for permissions to use the network, if it is executed without the --allow-net
-flag.
deno run app.js
┌ ⚠️ Deno requests net access to "0.0.0.0:7777".
├ Requested by `Deno.listen()` API.
├ Run again with --allow-net to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) >
The above message states that accessing the network is denied and the application should be run using the --allow-net
-flag. We will learn more about Deno as the course progresses.
Question not found or loading of the question is still in progress.
A response for every request
Deno passes information about the request to the function that handles the request. To see the information, we need to a parameter to our function. In the following example, we have added the request
parameter to the function handleRequest
.
const handleRequest = (request) => {
return new Response("Hello world!");
};
Deno.serve(handleRequest);
Each request is an instance of Request. We can access request information through the instance properties of Request. As an example, if we would wish to log the request method and the url, we would access the method and url properties of the request.
const handleRequest = (request) => {
console.log(`Request method: ${request.method}`);
console.log(`Request url: ${request.url}`);
return new Response("Hello world!");
};
Deno.serve(handleRequest);
When you run the application and access it with a browser, you notice something interesting.
deno run --allow-net --watch app.js
Listening on http://localhost:8000/
Request method: GET
Request url: http://localhost:8000/
Request method: GET
Request url: http://localhost:8000/favicon.ico
As we see from the logs, instead of one request, there are two. This highlights that browsers do things that we might not always be aware of.
We'll next briefly look into debugging applications, after which we look in more detail into using information from the request to shape the response.
JavaScript primer
The course expects that you have prior programming experience. Prior JavaScript knowledge is not required. At this point, if you haven't worked with JavaScript, check out the JavaScript primer.