Checkpoint 3
Learning Outcomes
Can implement a web server with endpoints following a REST API specification.
Able to write tests that sends HTTP requests using test framework like supertest.
Can design and build a web frontend based on a specifcation.
1. Introduction
Up to now, and maybe without realizing it, you have been developing the server side (backend) of a web application. In this checkpoint, you will give your project a frontend (AKA a client-side implementation)! A frontend allows a non-technical end user to access your project through a user interface (UI). The previous two checkpoints built the backend of your application and although your tests can access your methods, it would be difficult for an end user to make use of them. In this checkpoint, you will complete your application by building a web frontend to allow a user to access to your backend methods (addDataset, removeDataset, listDataset, and performQuery).
We will provide two frontend specifications, Section Insights and Campus Explorer, and you will select one of the two to implement. Section Insights focuses on giving users insights into the sections datasets with figures and graphs. Campus Explorer will allow users to visualize the campus buildings and access the rooms data.
One core activity that is common to both frontends is evolving your existing implementation to be a server. C3 involves implementing a REST API server, which your frontend will use to communicate with your existing implementation.
2. Grading
We will check for copied code on all submissions, so please make sure your work is your own.
Your grade for Checkpoint 3 will be 30% from AutoTest grading of your server implementation and 70% from a manual assessment of your frontend implementation.
2.1 Server Implementation (30%)
As with C1 and C2, the Server Implementation will be graded by AutoTest and you will submit your code via your Github repository. We will grade every commit on the main branch of your repository. Your grade will be the maximum grade you received from all commits on the main branch made before the checkpoint deadline.
AutoTest will behave in the same manner as C1 and C2. To request the associated smoke test feedback, you can comment with @310-bot #c3 on the merge commit of interest on the main branch. As with prior deliverables, #check feedback will be available on all branches.
2.2 Frontend Implementation (70%)
Frontend requirements details, and how submit your implementation, are described in detail below. Your team must implement all of the user stories that were created for Journal 2, in addition to implementing one of the two frontends.
3. Server Implementation
You will implement a web server to surface your InsightFacade methods to enable a frontend to access those methods via HTTP requests. Your Web server will need to provide the following REST endpoints exactly as they are specified, because your client (aka. AutoTest) will leverage on these endpoints to access your InsightFacade methods. Below is a list of the REST endpoints your Web server must support.
PUT /dataset/:id/:kind allows one to submit a zip file that will be parsed and used for future queries. The zip file content will be sent 'raw' as a buffer in the PUT's body, and you will need to convert it to base64 server side.
Response Codes:
200: When InsightFacade.addDataset() resolves.
400: When InsightFacade.addDataset() rejects.
Response Body:
{result: arr}: Where arr is the array returned by a resolved addDataset.
{error: err}: Where err is a string error message from a rejected addDataset. The specific string is not tested.
DELETE /dataset/:id deletes the existing dataset stored. This will delete both disk and memory caches for the dataset for the id, meaning that subsequent queries for that id should fail unless a new PUT happens first.
Response Codes:
200: When InsightFacade.removeDataset() resolves.
400: When InsightFacade.removeDataset() rejects with InsightError.
404: When InsightFacade.removeDataset() rejects with NotFoundError.
Response Body:
{result: str}: Where str is the string returned by a resolved removeDataset.
{error: err}: Where err is a string error message from a rejected removeDataset. The specific string is not tested.
POST /query sends the query to the application. The query will be in JSON format in the POST's body.
NOTE: the server may be shutdown between the PUT and the POST. This endpoint should always check for a persisted data structure on disk before returning a missing dataset error.
Response Codes:
200: When InsightFacade.performQuery() resolves.
400: When InsightFacade.performQuery() rejects.
Response Body:
{result: arr}: Where arr is the array returned by a resolved performQuery.
{error: err}: Where err is a string error message from a rejected performQuery. The specific string is not tested.
GET /datasets returns a list of datasets that were added.
Response Codes:
200: When InsightFacade.listDatasets() resolves.
Response Body:
{result: arr}: Where arr is the array returned by a resolved listDataset
The :id and :kind portions above represent variable names that are extracted from the endpoint URL. For example, in the PUT URL http://localhost:4321/dataset/mysections/sections, mysections would be the id and sections would be the kind.
3.1 Bootstrap Code (Required)
We will provide starter code for the Web Server as a pull request against your main branch. Once you merge this pull request from 310-bot, you will have three new files in your project associated with the implementation of a Web server:
src/App.ts contains the source code for starting the application and initializing the server. This will be given to you for free.
src/rest/Server.ts contains the logic for your server.
test/rest/Server.spec.ts contains the tests for your server. You'll want to write your own Server tests here!
Both the Server.ts and Server.spec.ts files will contain some sample code to point you in the right direction. We will use express as our REST server library. Please refer to its documentation!
3.2 Testing the Web Server
Your local tests for the endpoints you implement in Server.ts should exist in Server.spec.ts file. The same libraries and frameworks as before (Mocha, Chai) will be used for testing, with the addition of SuperTest. SuperTest is used to send HTTP requests to your backend endpoints within a test case. Your tests will have to send requests to your backend and check the received responses for validity. You will want to use the debugger to inspect the received responses to determine the exact format of response and where to find the values you want to assert against.
4. Frontend Implementation
For the frontend implementation, you will create a fully functional web interface. You will implement one of two specifications: Section Insights or Campus Explorer. The goal of both frontends is to allow users to view and learn information about the datasets on your server.
Additionally, you must implement the user stories that you specified in Journal 2. The demo for these user stories will be assessed in the Journal 3 oral discussion lab after the C3 deadline, where you will be asked to demonstrate the overall usability of your system. Thus, it is important to design your frontend with usability in mind, not just basic functionality!
Important: You can add new dependencies (ie. run yarn add ) for your frontend, but these dependencies must be contained within the /frontend directory. (You'll likely have a second package.json in your frontend directory).
Web Frontend Bootstrap (Optional)
For either frontend specification, you can choose to use the provided basic web frontend bootstrap if you wish. This bootstrap is completely optional; if you prefer, you may choose to configure any other library you would like, including React or Angular. The optional frontend sources will be available as an optional pull request on your repository. We’ve provided a simple implementation that contains a button that when clicked shows an alert.
If you merge the optional PR to use our bootstrap, you will need to uncomment the following line in your Server.ts file:
this.express.use(express.static("./frontend/public"))
This line is what serves your frontend UI sources to the root of your application.
The subdirectory /public contains the static sources that will be hosted by your Web app:
index.html contains the starter HTML code for the UI. This file is hosted by the GET / endpoint of your REST server. This will already be implemented in the bootstrap.
style.css contains the CSS styling of the UI.
frontend.js contains the logic to listen to the button click event and show an alert.
There are two new aspects to the Web frontend that you haven't seen in prior checkpoints:
1. Plain JavaScript. While it is theoretically possible to develop the frontend in TypeScript, you are also welcome to use plain JavaScript.
2. Browser. You will dive into the world of browsers with your frontend implementation. Your frontend code will be run in the browser and will communicate with your Web server via REST/Ajax calls. This means also that you will have the global window, document and XMLHttpRequest objects from the browser available anywhere in your frontend code.
4.1 Submitting your frontend work
You will submit a video demonstrating your frontend implementation. This video must be uploaded online with the link specified in the /frontend/README.md file. You are responsible for choosing a location that the TAs can access while grading, e.g., a YouTube link.
The video demo must satisfy all of the below requirements to get full credit. Failure to follow all of exact instructions below will result in grade reductions:
1. The demo must be uploaded online, and be accessible via a link (URL). The link must be present in the /frontend/README.md file of your project.
2. The demo must be a continuous screen recording. We are not expecting a polished work of art, for example, you may need to restart your server during your demo and that is ok!
3. Include audio explaining what you are doing. You can easily add a microphone to the default screen recording provided by both Windows and Mac.
4. Demonstrate the required behaviour as described in the specification, and show the Network Request when a network request is going to your server. For example, when a user adds a dataset, there will be a corresponding call to your API to add the dataset. You need to show this Network Request in your video. It may be easiest to just keep the Network tab of the development tools in your browser open during the entire demo.
Showing the Network Request upon the user doing the action. To do so, open the developer tools in your browser and navigating to the "Network" tab. When performing the action, a network request will go to your server.
5. Be under 10 minutes. Most demos will be between 2-6 minutes.
4.2 Section Insights Specification
The Section Insights frontend allows users to add and remove sections datasets, and provides visual insights into those datasets.
4.2.1 Implementation Details
Adding a Sections Dataset
A user should be able to add new datasets to your application through the browser (frontend). Your application needs to:
Allow the user to create their own ID (via an input of some kind)
Allow the user to choose which zip file from their computer to upload
Provide feedback if either the ID or the dataset is invalid
Provide feedback if the dataset is added correctly
After successfully adding the dataset, the user interface should update to include the added dataset. No page refresh: there should be no page refresh between when the dataset is added, and when the user interface is updated. If you need to refresh the page to see the updated user interface, then your frontend does not meet this requirement.
Removing a Sections Dataset
A user should be able to remove existing datasets from your application through the browser (frontend). Your application needs to:
Allow the user to remove a dataset
After successfully removing the dataset, the user interface should update to remove the deleted dataset. No page refresh: there should be no page refresh between when the dataset is removed, and when the user interface is updated. If you need to refresh the page to see the updated user interface, then your frontend does not meet this requirement.
Viewing Added Datasets
A user should be able to know which datasets are currently added to your server through the browser, where each dataset is recognized by its ID. Your application needs to:
Display the ID of each added dataset
Dataset Insights
The most important part of this frontend is enabling users to gain insights about the added datasets. For each added dataset, a user should be able to view three insights about the data they contain. These insights should be a visual representation using some kind of plot or graph. A number or table will not count as an insight. Be creative and thoughtful!
These insights should reflect useful and interesting insights a user may want to gain by using your application. To create these plots and/or graphs, you will likely want to use a third party library like d3 or chart-js. Your application needs to:
For each added dataset, display three plots or graphs that provide useful insights into the data they contain.
4.3 Campus Explorer Specification
The Campus Explorer frontend focuses on enabling users to view building information on a map, and learn about the relationships between rooms from rooms datasets.
4.3.1 Implementation Details
Viewing Buildings on a Map
A user should be able to view the locations of the rooms in the C2 rooms dataset on a map. Your application needs to:
Display a base map (e.g., using Google maps).
Include markers on the map for each building within this dataset.
Room Insights
A user should be able to view detailed information about each room, and the relationships between rooms, in the dataset. Your application needs to:
Allow users to select between 0 to 5 rooms. Please ensure your demo shows each of 0 rooms selected to 5 rooms selected.
For each selected room, the user should be able to see the room's fullname, shortname, number, address and seats.
If two or more rooms are selected, then relationships between rooms should appear. For each pair of rooms, the UI should estimate the walking time between them. This estimate should be roughly accurate, where two rooms within the same building have a low walking time, compared to the walking time between buildings.
Note: for this specification, you are not required to handle uploading a dataset from the UI. Instead, you could find a way to call addDataset by submitting a zip to one of your REST endpoints using Postman or curl.