BusBoard

Learning goals

  • Using REST APIs
  • Linking different sources of data
  • Error handling

Programs used

Problem background

Application Programming Interfaces (APIs) are everywhere. They provide a way for a developer to interact with a system in code. Look at the page here. It shows the next few buses due to stop near King’s Cross Station. This is great for an end user, but if you wanted to get this information and use it in your program, that page wouldn’t be very useful.

Fortunately, TfL provide an excellent set of APIs which allow third-party developers (such as you) to get live data about many things, and use them in your applications. Your aim is to build an application which, given a postcode, finds the two nearest bus stops, and shows the next five buses due at each. We’d like to run this on a display so that people can see when the next buses are.

Getting started

First, register at the TfL API Portal. Most of the options are unimportant, but to clarify: You’re going to be building a website / browser-based application, targeting bus users, with an estimated 2 users (yourself plus your trainer). You only need access to the “Core datasets”.

Now go to the StopPoint API page. This gives details of the different operations you can perform against the TfL API, and lets you try them out.

For example, click on “Gets a distinct list of disrupted stop points for the given modes”. Enter “bus” for the “modes” parameter, and click Try. You should see:

  • A “Request URL”. That’s what you’re sending to TfL.
  • A “Response Body”. You should recognise it as JSON. It contains a list of bus stops currently experiencing disruption. (There are probably quite a lot of them.)

Take the “Request URL” and paste it into your browser. You should see the same JSON response, probably not so nicely formatted (depending on your browser).

Troubleshooting

If you have any trouble with requests loading indefinitely now or at later points in the exercise, check that the request has the domain name “api.tfl.gov.uk”, not “api.digital.tfl.gov.uk” (the site might generate the second one, and it might not work)

You should also supply your “Application Key” in your request. TfL might decide not to accept your request without this. Go to the TfL API Portal and click on “Profile” – two keys should be listed (either work). If it isn’t, go to “Products” and select “500 Requests per min”, then enter the name you want and click subscribe. After this the keys will be listed on “Profile”. Now edit the URL to add these as query string parameters: ?app_key=123 (replacing the key appropriately). Check that you still get the same response back.

Now that you’re set up, have a play about and see if you can work out how to get live arrival predictions for King’s Cross (The stop code is 490000129R). Do ask for help if you get stuck.

Postman

You may find it helpful to use a tool like Postman or Hoppscotch to manage your API requests while you’re testing. It makes it a lot easier to understand the request you’re making by breaking down the components of the URL. It also has built-in syntax highlighting, which will make the response a lot clearer to read.

New console application

We want to create a new console application for this exercise, by running the following in an empty folder: npm init -y

Then inside package.json, add the following line inside the scripts object:

    "start": "node .",

Then create a new file index.js containing:

function main() {

}

main();

Finally create a git repo to track the project by running git init

Bus times

Once you’re returning sensible data for a given stop code, we need to turn this into a program. Your program should ask the user for a stop code, and print a list of the next five buses at that stop code, with their routes, destinations, and the time until they arrive in minutes.

Below is some example code for making a GET request in JavaScript; note that this returns a Promise.

function makeGetRequest(endpoint, parameters) {
    const url = // insert url
    return new Promise((resolve, reject) => 
        request.get(url, (err, response, body) => {
            if (err) {
                reject({status: response.statusCode, href: url, error: err});
            } else if (response.statusCode !== 200) {
                reject({status: response.statusCode, href: url, error: body});
            } else {
                resolve(body);
            }
        })
    );
}

Your console application should take a bus stop code as an input, and print out the next 5 buses at that stop.

Remember to commit and push your changes as you go.

Bus stops

It would be better if the user could just enter a postcode, rather than the stop code. Finding out stop codes is difficult, but everyone knows their postcode.

You will need to call two different APIs to make this happen:

See if you can work out how to wire these two APIs together. Then modify your program so that the user can supply a postcode and see the next buses at the two nearest bus stops.

Don’t forget logging and error handling

Are you confident you’ve handled anything that can go wrong?

  • What happens if your user enters an invalid postcode?
  • What happens if there aren’t any bus stops nearby?
  • What happens if there aren’t any buses coming?

Journey planning

The TfL API also has a “Journey Planner”. Edit your program so that (when requested) it will also display directions on how to get to your nearest bus stops.

Stretch goals

What else can you do with the API?

For example, you could edit your program to:

  • Plan a journey to any postcode in London
  • Check for any disruptions
  • Provide a list of a bus’s upcoming stops and estimated times

If there are other features you can think of, have a go at implementing them too.