Contents:

Introduction

In a previous assignment, UW Marketing commissioned you to write a route finder tool. Marketing is pleased with your initial results, but now they've asked for a graphical user interface (GUI) that visually draws routes on a map.

You will build your GUI using React (like in the Connect the Dots assignment) and the Spark Framework. Unlike the pathfinder and Connect the Dots assignments, this time you are building both the frontend and the backend! You will get practice using these tools, event-driven programming, and the model-view-controller (MVC) design pattern. You'll probably write less than 50 lines of Java code and about 250 lines of TypeScript to complete the basic requirements.

You are expected to fix any bugs from previous homeworks that affect the correctness or performance of your application in this assignment. You are also required to fix code quality/organization issues in your pathfinder code.

When you're done, you can show off your awesome looking campus-map-route-finding application to your friends and family!

The Overall Picture: What is CampusPaths?

An Overview of the CampusPaths Application

The above diagram is an overview of the basic structure of the application that you'll be building in this assignment. Note that there are two servers this time around. In the Connect the Dots assignment, you had one client (Google Chrome) and one server (the React server). The React server is a part of React, not something you needed to write. It was the React server's job to put all the different parts of your application together before sending it to Google Chrome to be shown to the user. In this application, the React server has the same job.

The additional interesting part of this assignment is the second server, which is a server you'll be writing in Java using the Spark Java framework. There are many more details in the "Backend" section of this assignment spec, but the main job of the Java server is to allow the React application to access the campus paths data. This might take the form of requesting information about buildings on campus, or asking the server to calculate the shortest path between two buildings and respond with the answer. Fortunately, you've already written all the Java code you need to manage this data and perform those calculations, you just need to create a server the allows clients (like your React app running inside Google Chrome) to make requests for data.

Roadmap: Suggested Path Through This Assignment

In an effort to give you a clear path to completing this assignment, there is a suggested order listed below. You are not required to complete this assignment in this order, but it might be helpful to.

In designing your React frontend in more detail, it may be helpful to read the React documentation's Thinking in React section (as well as maybe the Lifting State Up section for some more gritty details). The "Thinking in React" section walks you through a simple application built in React, and discusses how a React developer might start with an idea of an application and work her way up to having a completely functional application. You certainly don't need to follow that section step-by-step, but it has some suggestions about what to think about when you're designing at a high-level, and your final application needs to use good React style.

Backend: Your Spark Java Server

Since you already know the basics of creating a React application from the connect the dots assignment, the backend is where you'll encounter the majority of the new material for this assignment. Fortunately, Spark is a very simple Java framework that requires very little code to get a fully-featured Java server running. You saw Spark in lecture, so we won't be repeating all of the basics here. If you're curious, Spark has some documentation on their main webpage, and they also offer a complete set of javadocs for the API. We're providing a class called SparkServer (inside hw-campuspaths-server/) with a main method that is where you should create all your routes and do any other initialization that you may need to. (For example, you probably want to create an instance of CampusMap that you can use to fulfill requests that are sent to your server.) Note that you should not create a new CampusMap each time your server receives a request, because then all the work of loading data and creating a graph needs to be repeated for each request, slowing your application down.

Creating this application shows us exactly why the Model, View, Controller design pattern is so helpful. You originally implemented the CampusMap class to be used with the text user interface from the pathfinder assignment, but now you'll be able to reuse parts of it for this assignment without having to modify it much (if at all). Separating the model (all your graph code, pathfinding code, and parsing code) from the view and controller in the pathfinder application by using CampusMap (and the ModelAPI interface that it implements) has made it much easier to reuse all of that code for something completely different!

You should implement a Spark Java server that allows other applications to make requests to query data and computation from your preexisting pathfinder application. You're writing this server specifically to support the React application that you'll be building, so you can design this server to respond to exactly the requests that your React application will make. Your SparkServer class shouldn't do much more than contain a the main method and define all the different routes in your application - your routes will probably only do a very small amount of processing and leave most of the work to calling the methods of a CampusMap object. You're free to create whatever routes make sense for your overall CampusPaths application, the server will probably be very minimal. For reference, the staff solution only has two routes, and those two routes do almost no processing other than call methods inside CampusMap. You may modify CampusMap, but you probably don't need to in order to fulfill the base requirements of this spec, and you should do so carefully. In particular, you should not change/break any preexisting functionality - the pathfinder application should still work as it did before this assignment.

Using JSON to Send Data

One of the trickiest parts of communicating between two separate programming languages, like Java and TypeScript, is effectively sharing data between them. A Java object works completely different from a TypeScript object, so how are we supposed to send information from the server about paths, and buildings, and other campus data, and have the TypeScript code in your React app be able to understand it? This is where JSON comes in. JSON stands for TypeScript Object Notation: it's a way to take a TypeScript object and turn it into a string that represents it. The powerful thing is that you can also go the other way: take a JSON string and turn it into an actual TypeScript object that you can then pass around, read fields of, and update as you wish. To solve this problem of communication, we're going to have the server always respond to requests by sending a JSON string. That way, the TypeScript code that made the request can just turn the JSON string into an object and read the fields inside that object to get the information it's looking for.

How do we take a Java object inside our server (maybe one that represents a path, or some other data that we want to sent) and turn it into JSON? The folks at Google realized a while back that they had this same problem and invented something called Gson that can do just that. Gson is an extremely powerful and feature-filled Java library, but the basic idea is that it can take a Java object and turn it into a JSON string that contains all the same data. (It can actually go the other direction too, take a JSON string and turn it into a Java object, but that's a much more complicated process and not necessary for this assignment.)

We now know the basic ideas behind this server: when your React application makes a request to it, one of the routes you defined in your Spark server is run. That route's handle method should get any additional info from that request (if there is any), and call methods of CampusMap to get the information that was requested. Then, the handle method will use Gson to turn the response data into a JSON string, and return that JSON string. Spark will take the String you returned from the handle method and send it back to your React application that made the request.

Running and Testing Your Server

To start your server once you've written some code, use the provided hw-campuspaths-server:runSpark gradle task. Note that gradle will start the server and then keep running, you won't get a "BUILD SUCCESSFUL" message until after you stop the server. Also note that, unlike React, if you change any of your Java code, you won't see the changes right away. You'll need to completely stop and re-start your server to have the new changes take effect. You'll see in the starter code (SparkServer.main) that there's a CORSFilter object that's created, and has the apply method called on it. You should not remove or modify this code, and you should leave it at the very top of your main method. This just sets up some extra settings to make sure that the React application and the Spark server can talk to each other even though they're running on different ports. (React is running on port 3000 and Spark on port 4567 – normally this isn't allowed for web security reasons, but the CORSFilter object tells Google Chrome that this is OK.)

Once you've got some of your server running, you probably want to test it. Fortunately, you don't need to create the whole GUI before you can test it. Since requests to the sever are just made up of web addresses, you can send a request to your server by hand and see what the results are. (Note that you don't need to do any automated or unit testing for the server code you wrote, manually checking that your server is working is enough.) First, make sure you've started your server and that it's running. Then, open Google Chrome and, in the address bar, type:

localhost:4567/YOUR-ROUTE-HERE

You can replace "YOUR-ROUTE-HERE" with any route that you've defined (and optionally add query parameters as described in the slides from lecture) to send a request to your Spark server. The JSON string that your server sends back will be displayed in the browser window as plain text. Try sending a couple requests for paths between buildings on campus and make sure the server looks like it's sending the right thing back. Congratulations, you're now the proud owner of a shiny new Java web server!

Frontend: Your React Web Application

Now that you've created this fancy server, it's time to create a React application that'll use it! Here's your chance to get super creative: you can design your GUI application to look however you want, as long as it meets some basic requirements that we're outlining below. Most of your time on the assignment will probably be spent creating the GUI. While this interface is a little more complicated that what you did in the Connect the Dots assignment, and there isn't as much provided starter code, the core concepts are the same. You're encouraged to look back the the code you wrote in the Connect the Dots assignment and the lecture/section slides and demo code about React to remember how to structure a React app and create your own components.

You'll be creating your application in hw-campuspaths/, most of your code will go in hw-campuspaths/src/ and there is a provided image file of the campus map that you should use in hw-campuspaths/public/. You are encouraged to use the provided starter code that loads the image and sets up the canvas to be the same size as the image. If you want to modify or replace this starter code, you're welcome to, but beware that canvas sizing can be very tricky to get right. Note that aesthetics do not matter for this assignment. As long as your interface is easily understandable and usable, it doesn't matter how ugly it looks. You're welcome and encouraged to make it pretty if you'd like, but wait until you have all the required functionality complete first before doing so.

Remember the basic commands for getting your React application up and running: npm install the first time you start working on this project, and npm start to get your React server running. You should run these commands from hw-campuspaths/. (To see what directory you're currently inside, use the pwd command. To change into a directory, use the cd command. This means that if you're in the base directory of your repository, use cd hw-campuspaths to change into the correct directory.)

The following are the requirements for your application to get full credit. Note that a lot of these are open-ended: you're free to choose how to implement them and design the interface for doing so yourself. However, it must be easy and intuitive to understand how to use all the features described below.

Your campus paths GUI must:

Beyond these requirements as listed, you're allowed to do whatever you'd like to make this application your own. Make sure you've completed the basics of this application before you spend too much time experimenting.

Sending Requests to your Spark Server from React

Sometimes your React application will want to send requests to your Spark server to get data to display, this may be in response to some user input, or just as the React application is setting itself up for the first time. TypeScript can make web requests from inside the browser by doing a "fetch".

A fetch is just like a normal request, as if you were typing a URL into your browser address bar and looking at the output in the window. Instead of using the browser GUI, though, you create the URL to request inside TypeScript, and the response to the request is returned to you in the TypeScript for you to do whatever you want with. The fetch documentation has a few sections that'll be particularly important to check out: "Response/Body", and "Checking that the fetch was successful". Remember that your application should be able to gracefully handle errors that the server reports (or if the server never responds, such as if it was never started). Note that the examples in that documentation use the traditional Promise syntax for TypeScript. You're welcome to use that if you'd like, but we highly recommend (and support) the async/await syntax for dealing with Promises, which will look different. In particular, you won't need calls to .then() or .catch(), instead using keywords like await or try/catch blocks. See the section demo code and section slides for more information and examples on using fetch to communicate between the server and your React application.

In the industry, there are some technologies that can be used for testing GUIs. However, they are often complicated and are definitely beyond the scope of this course, so you don't need to worry about any sort of automated testing for your GUI or your TypeScript.

General Advice

Remember to think about where you are in the React lifecycle whenever you're writing code, and make sure that what you're doing is always appropriate for that place in the lifecycle. See the Connect the Dots code for examples of proper lifecycle management. Make sure you're always using good React style: don't use document.getElementById or similar methods, the only call to ReactDOM should be in index.tsx (we provided it for you), and you should use state and props correctly. In the React documentation, there is a sidebar on the right labelled "Main Concepts." In that sidebar, sections 5 (State and Lifecycle), 10 (Lifting State Up), and 12 (Thinking in React) might come in handy for this assignment in particular, and are recommended, though they can be slightly more advanced that we're used to.

Optional Extra Features

You're encouraged to express your creativity with this assignment. Once you have a complete, working version of the basic assignment as described above, commit a final working copy to your repository so you'll always be able to go back to it in case you need to. Then, consider implementing some extra features or improving the visual aesthetic of your application.

The only rule for extra features is this: don't break existing rules or feature requirements. None of the things you add should get in the way of your application satisfying the requirements outlined in this spec: you're still bound by those requirements even if you do extra stuff. Outside of that: go crazy! Some ideas are listed below, in no particular order:

For this assignment, you're allowed to edit hw-campuspaths-server/build.gradle and/or hw-campuspaths/package.json if you'd like to add additional libraries to help you implement these extra features only. Be absolutely sure you know what you're doing, and that you don't change/break any preexisting functionality of those files. The staff isn't able to support any additional libraries you may add to your application.

If you decide to add any additional features to your application, document them in hw-campuspaths/extras.txt. If the functionality/features you add show significant effort, you can earn some extra credit for this assignment! Note that purely aesthetic changes, like changing the font or the background color, aren't enough to warrant extra credit. Only features documented in extras.txt will be considered for extra credit. Again, make sure your additional features don't break any of the functionality that is required above. Extra credit can help you earn back points that you lost elsewhere in this assignment, or might be considered when determining final grades for this course, but it's ultimately a small source of additional points.

Useful Info, Common Issues, and Other Hints

Resources: Useful Links all in One Place

Assignment Submission

What to Turn In

You should pull, then commit and push all changes you made to your model, including and especially your CampusMap class. Include all changes/additions you made to the SparkServer class. Additionally, make sure to include any changes you may have made to build.gradle and/or package.json, and include all of the .tsx and other files that you created in hw-campuspaths/. Don't forget to document any extra-credit additions you made in extras.txt.

You should use the tag hw9-final for this assignment.

Refer to the assignment submission handout for complete turn in instructions.