UCombinator

Startup Submission 06: Adding a Web Server

In this submission, you will replace your mock server with a real server, using Express and Node.JS. You will perform the same procedure for your startup project as you did for Facebook in Workshop 9. We urge startups to pay attention to the grade rubric – as in prior assignments, we will grade your submission according to that rubric.

If your startup followed all of the guidelines of the previous submission, you will likely find this submission to be much less work than the last! However, if your startup had trouble last submission, you are going to need to do extra work to fix those problems before adding a server.

Most of the components of this submission mirror the changes you had to do to Facebook for Workshop 9. Below, we break down what you need to do for this submission.

Fix Issues with Previous Submission

You should attempt to fix all of the major bugs and issues present in your previous submission. Critically, if your dynamic mockup submission did not use the server correctly, you need to fix this issue before you are able to use a real server.

Specifically, before you can even add a real server, the client-side of your project must:

  • Use the mock server and mock database appropriately.
    • If you are not using emulateServerReturn in your server methods, you will not be able to migrate that server method to the real server. There is no way to write a server method that uses return to send data to your application. It is all callback based.
    • It is unacceptable to use database functions like readDocument/writeDocument/etc directly in your components or helper modules. You can only use these methods in the mock server. Moreover, in this submission, you are moving the database from the client to the server, so you will be forced to make this change regardless.
  • Be dynamic, and not include any hardcoded data except for the ID of the currently logged-in user.
    • The only exceptions are static pages, like FAQ pages, that do not need to read from the database.
    • If your server submission includes hardcoded data in your React components, expect heavy penalties.
  • Have functioning forms.
    • If you have a form to, say, update a user’s profile or write a status update, submitting the form should appropriately update the database. The result should be visible somewhere in the UI, if applicable.
    • Some forms do not update the database or have a visual impact on the UI. For example, email forms merely send an email using the server.

You should also consider fixing the following issues, which are not blockers to adding a server:

  • Implement missing features or remove dead links. If your product has links to unimplemented features, consider implementing or removing these features. Make sure your product still has sufficient complexity for each startup member to be responsible for a HTTP route.
    • If you aren’t getting serious about implementing the feature now, there’s not much time for you to implement it later!

If you are doing the above properly, you will not be marked down significantly for small bugs or inconsistencies in your product so long as they are mentioned in the report.

HTTP Resources and Requests

You should map the database entities that the application needs access to to HTTP resources, like we do in Workshop 9. For example, we map users to HTTP resources at /user/:userid. We recommend that you decide upon these resources as a group – otherwise, your startup may use inconsistent HTTP resource paths!

Then, you should determine the HTTP requests to use for each of your server functions in the client’s server.js. Namely, you should figure out:

  • What verb to use (e.g. GET, POST, PUT, DELETE…)
  • What resource to target (e.g. /user/:userid)
  • What body to send with the request, if any.
  • The expected body of the server’s response, if any.

Workshop 9 walks through this process for all of the server functions for Facebook. Your decisions here will impact the HTTP routes you configure in Express.

JSON Tokens and Authentication

Around the same time as HTTP request planning, you should settle on a format for your JSON web token. What information do you need to store in the token to authenticate HTTP requests?

In Workshop 9, you implement a JSON web token that only contains the user’s ID, which is all of the information Facebook requires to figure out if a user has access to read/modify particular data in the database. It is possible this information alone is sufficient for your application, as well.

As in the workshop, you will use unencrypted and base64’d JSON tokens for authentication. See the workshop for details on how to generate these for the client, and how to use them on the server.

Express HTTP Routes

After deciding the HTTP requests you need to support for your application, implement them in the Express server. Each startup founder should be responsible for at least one HTTP route in the server, stemming from a product feature they are responsible for (see report and grade rubric sections for individual grade details).

Each HTTP route must:

  • (If it expects JSON in the body) Perform JSON schema validation on the body of the HTTP request
    • You did this in the workshop for status updates and comments.
  • (If applicable) Determines if the requester is authorized to make the specified request using the JSON web token.
    • All of the HTTP routes in the workshop make this check.
    • Naturally, if the request involves public data, you may not need this check. But you will need to defend this decision in the report.
  • Respond to the request with appropriate HTTP status code in the event of a success / authentication failure / etc.

Client Reset Database Button

Move the code from the ResetDatabase component in database.js into its own JavaScript file. Change the component so it communicates with the server to reset the database. You may re-use the code from Workshop 9 to make this change.

In addition, implement an HTTP route on the server for resetting the database, as we do in Workshop 9.

Client Database Removal

As in Workshop 9, you will need to move your mock objects from your client’s mock database to the server’s mock database. Then, you will need to change all of your mock server methods to communicate with your Express server.

Once the transition from mock server to real server is complete, delete the mock database from your client Git repository using git rm. Your client should no longer need it.

Client Error Handling

The client-side of your application must report server errors to the user, much like Facebook in Workshop 9. You may re-use some of the code from Workshop 9. In particular, the sendXHR helper and ErrorBanner will likely be useful!

Like in the workshop, if the following happens, the user should be notified about it in some way:

  • The server is not running.
  • The server unexpectedly rejects a request with a non-successful status code.
  • The server fails to respond to a request in a timely fashion.

You should try to do this early on, as it will make it much simpler to debug server errors!

You can choose to crudely report the raw error details to the user, like we do in Workshop 9, or you may attempt to make the errors more user friendly. It’s up to you! :)

Expectations for Search, Email Forms, Third Party API Integration, and Other Features

In this submission, you should try to implement any of the server-based features you have been putting off implementing. Please make sure the other components of your submission are complete before you start spending a significant amount of time on these features; it is much more important that your product is using the server properly than it is to implement these features!

We have updated the mock database so that it supports retrieving collections, so you can emulate basic database queries to implement search and other filtering requests. The modified Facebook client in Workshop 9 supports basic search using the new database functionality. If your desired queries are complex, you can implement a “dumbed down” version for now. For example, the Facebook client in Workshop 9 only searches for text in the content of a Status Update, and not the other fields.

If your product has a send email form, you should implement a route on the server that actually sends the email. We recommend NodeMailer for this purpose. Be careful: NodeMailer typically requires the username/password to an email account to send email, and you should not commit this information to GitHub! You may want to include instructions in the report for how to configure your project so that the feature works.

If your server or client needs to communicate with an external API (e.g. Spotify, GitHub, etc), you should start working to integrate with that API. Many of you will likely discover that the API uses HTTP requests, much like your startup product! We understand the difficulty of working with a new API like this, and will understand if your final submission has some rough edges. Please document any limitations.

If integration with a third party API proves too challenging, you can change the design of your product to avoid the integration. For example, if you planned to integrate with Amazon to grab a user’s purchase history, you may change your product so users enter their purchases manually into your app. Document any changes like this in your report.

Report

Include a report in reports/submission_06.pdf in your client repository with the following information. Note that we are no longer requiring you to include or update your ER diagram, but your product will have issues if your objects are not structured properly! Keep in mind the lessons from the workshop on data modeling as you design or refactor objects in the database.

Report: HTTP Requests / Routes

In the report, include a list of HTTP routes implemented in the server, and the mock server method that they replace. For each, briefly describe:

  • The verb, target, and body of the request.
    • Example: POST /feeditem [feeddata], where [feeddata] is a JSON object describing a Feed Item.
  • What the HTTP request does, and what mock server method it replaces.
  • What resources the HTTP request creates/modifies/etc.
    • Examples: “Updates /user/:userid”, “Creates a new /user“…
  • Who is authorized to use the request
    • Example for PUT /user/:userid userdata: “A user with the specified :userid can issue this request. Administrators can also make this change on any :userid.”
    • Example for POST /feeditem feeddata: “The body of the HTTP request contains an “author” field containing a user ID. The requester must have the same user ID.”
    • If you have a hard time explaining it generally, feel free to include examples. Example: “A user with ID 4 can issue a PUT /user/4, but a user with a different ID cannot.”

Report: Special Server Setup Procedure

If your server has any advanced features that require additional setup besides npm install and node src/server.js, include a section in the report that describes how to set up these features. Include details on how to tell if the feature is working properly.

Report: Individual Contributions

Include a section that describes each startup founder’s contribution. Each startup founder should be responsible for at least one product feature and its HTTP route(s). Name the feature and the HTTP routes that the founder implemented / was responsible for.

Report: Lingering Bugs / Issues / Dropped Features

If your application has any lingering bugs, issues, or missing/dropped features, include a section listing these.

Grading Rubric

  • 5%: Report clearly describes all implemented HTTP routes, what they do, what mock server method they replace, what resources they operate on, and who is authorized to use the request
  • 5%: Report clearly describes individual contributions
  • 5%: Product displays server errors when they occur
  • 5%: Client contains reset database button, server contains reset database route, and button works
  • 20%: Client is free of hardcoded data, and no longer uses the client-side mock database
  • 10%: Client’s HTTP requests make sense given the operations they perform / data they return / etc, and are implemented properly
    • Verbs makes sense, targets makes sense, body makes sense, sends JSON token when coming from authenticated user…
  • 20%: HTTP routes are appropriately implemented in the server
    • Performs authentication if necessary
    • Performs JSON schema validation if the body of the request contains JSON
    • Uses appropriate status codes
    • Works properly
  • 30% [Individual] Founder’s product feature is working properly, its HTTP route(s) are implemented properly, and the client is properly using the HTTP routes
    • The route should not simply be a copy of another route

Updating Git Repository

Workshop 9’s repository contains two folders: client and server. One member of your startup needs to perform the following tasks to update your repository to include the server component.

All startup members will need to re-run npm install in both the client and server folders to install the dependencies for the client and the server.

Trivia: As you may notice from your GitHub repository name, we initially expected to use separate GitHub repositories for client and server. However, that raises some server configuration issues, so we decided to avoid the issue by using one repository.

Move client files into client folder

From within your current git repository, have one of the startup founders run the following commands to move all of the client-side of your application into a folder called client:

$ mkdir client
$ git mv README.md app build package.json webpack.config.js .gitignore .eslintrc client/

Now, all of the Git-tracked files for the client-side of your application should be in a folder named client. Note that we did not move node_modules: That folder is ignored by Git, and should not be included in your repository.

Test that this works by cding into client, re-running npm install to re-create node_modules, then run npm run serve. If all works as inspected, commit and push your changes to GitHub.

The other founders of the startup are going to need to re-run npm install in the client folder, since you have relocated the project.

Modify client’s package.json

One of your startup founders should modify the "script" section of client/package.json to the following:

  "scripts": {
    "serve": "webpack-dev-server --content-base build",
    "watch": "webpack --watch"
  },

This will let you use npm run watch in your client repository, which is the same command you used in the workshop to rebuild the client-side of your application without running a webserver.

Verify that npm run watch works, then commit and push the change to GitHub.

Add a server folder

One startup member should download server.zip, and extract it into the Git repository. It should create a server folder, with a package.json and other files. Add the folder to git:

$ git add server/

Note that all startup founders must run npm install in the server/ folder to install server dependencies.

Then, commit and push the file.

Submission

Please submit the URL to your team respository to Moodle by the assigned due date.