- Understanding routing with express
- Implementing REST GET methods
- HTML forms
- Implementing REST POST methods
-
Make sure you are familiar with npm, running nodejs programs and sending requests via a browser. If not, look at the intro to node practical.
-
Create a new project by creating a new folder/directory and executing
npm init
. This will create apackage.json
file in the directory (accept all the defaults). In a new file called hello.js put the following program, which uses express to send a very simple message:const express = require('express') const app = express() app.get('/', function(req, resp){ resp.send('Hello world') }) app.listen(8090)
Try running this either on the command line or VSC terminal with
node hello.js
or directly from the Run/Debug options within VSC.
For this to work you will need to install the module
express
which you do withnpm install express
This will add
express
to the dependencies listed inpackage.json
and put the express module, and all its dependencies in thenode_modules
directory, which it will create. It will also create apackage-lock.json
file which records the exact version of the packages that you are using. If you are using git then you would usually add package.json to git, but notnode_modules
. It is common to addnode_modules
to your.gitignore
file so thatgit status
will not report any changes to it. Once your project is complete if you want to share it with others you only need to circulate the files you have written, pluspackage.json
andpackage-lock.json
. The contents ofnode_modules
are rebuilt just by usingnpm install
. Try that now: delete thenode_modules
directory and then runnpm install
to reinstate it.Start your web service with
node hello.js
Access the service via your web browser at the URL
http://127.0.0.1:8090
. What happens if you try to access athttp://127.0.0.1:8090/hello.js
? Note that the path in the URL after the server is controlled entirely by the paths defined in express. This is different to the simple server you set use usinghttp
in the intro to node practical, which responded to all requests on the relevant port.Lastly, edit your package.json file so that the
scripts
section looks like this:"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node hello.js" },
This has added the
start
script so that you can run your program simply withnpm start
This is not a big saving now, but it is a good idea to do this in case you change how you start your program (e.g. using nodemon) or if you have more than one server script and it is not obvious which one to use.
-
Now read about routing with express and do the following
- Add another GET route with a different path with another
app.get
definition that gives a different message (you could make this a wildcard if you wished) - Change this second route so that it takes a route parameter (i.e. a path with a : in it), see
the section called route parameters in routing with
express. Extract this value from
req.params
within the handler function and send it back. Have a look at the first handler function in the example on random numbers in the lecture if you're not sure. Test this out by sending an appropriate browser request like http://127.0.0.1:8090/wave/everybody: this should say something likewaving at everybody
- Add another GET route with a different path with another
-
Next you are going to access a variable encoded in a query string (i.e. the bit after the ? in the URL).
-
Add another GET route to your server, this time with no route parameter. Extract any person in the query string by accessing
req.query.person
. This is similar to the second handler function in the example on random numbers. Test it out with a request something likehttp://127.0.0.1:8090/w?person=bob
-
Build an HTML page (probably called
index.html
) with a form. Theaction
attribute of the form is the URL of where it gets submitted (your node page). You also need to include an input with thename
attribute set to the the name of the variable to be submitted (in this caseperson
). You might like to include a submit button, although the form will submit if you hit enter on a text input. Load theindex.html
page into your web browser, by usingopen with
from the file navigator. For now we are not serving the HTML page through our web server. When you submit the form, you should get response from the web page. Note that form is simply creating the URL for a GET request.
-
-
Make your GET request do something more interesting than just printing out the parameter: use the parameter as a search key. Firstly you need some data. I have provided some potato recipes for you, based on a response that I got from http://www.recipepuppy.com/. The format is JSON (JavaScript Object Notation), which is basically the same syntax that JavaScript uses for object literals (although there are some small differences, most notably that object keys must be written in quotes). So this file contains a list (array) of objects.
In nodejs you can use
require
for modules, but also for JSON data, so you can simply writevar recipes = require('./potato_recipes.json');
Make this a global variable (not usually a great idea), i.e. not defined inside any function, so that it is accesible from all of your handlers.
Do this with a new project (new directory, run
npm init
again) and define an endpoint (i.e. a route) which takes a query string parameter that is used as a search key, returning only those recipes that match. If you need help, then you can look at working with objects and Array in JavaScript. It doesn't really matter what you called your server script, buthello.js
is unusual: people often call it either server.js or index.js. -
GET methods are for reading data without changing state, whereas POST methods are for changing state. Officially, according to REST, POST is only for adding new entries, and PUT or PATCH should be used for updating entries. But in practice many APIs, including e.g. twitter, use POST for updates too.
-
Create a new HTML form page called
update.html
by copying yourindex.html
(or if you want you can include two separate forms inside the same HTML page). Add amethod='POST'
attribute to the form (the default method for forms is GET). If you submit this now (try it) you will get an error, because your server is not handling post request. -
Change your server to have a route
new
which is accessed via POST, with something like
app.post('/new', function( ...){ ...});
Link it up to your web page and get it going like it was before, except via POST. Notice that the URL no longer includes the query string: the form data is now submitted via the request body.
- Make your server add a a new recipe to the collection. Firstly add relevant fields to the form
in
update.html
, then update the server script so that it collects the values from the request, creates an object with those values in the correct properties, and adds it to the list of recipes with push. This data will stay only as long as the server is running. To extract variables from the body (i.e. POST variables) you will need to use the body-parser package. More recent versions of express include this by default, but you may have tonpm install body-parser
. This is known as express middleware i.e. something that plugs into express to handle particular types of requests. For now you just need to include this in your server code:
var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: false }));
Once this is done you can access POST variables in a request with
req.body.var_name
, just like you did with route and query values.- Test out your POST method: have two tabs open, one for adding recipes and another for searching.
-
-
The potato recipes were extracted from a one-off request that was made to an API. You could do this 'live' in your server code, perhaps using a package like node-fetch. Have a look through the directories of APIs listed at https://mixedanalytics.com/blog/list-actually-free-open-no-auth-needed-apis/ or https://apipheny.io/free-api/, and see if any of them could work with a web-site that you would like to build.