Startup Submission 06: Adding a Web Server
- Fix Issues with Previous Submission
- HTTP Resources and Requests
- JSON Tokens and Authentication
- Express HTTP Routes
- Client Reset Database Button
- Client Database Removal
- Client Error Handling
- Expectations for Search, Email Forms, Third Party API Integration, and Other Features
- Report
- Grading Rubric
- Updating Git Repository
- Submission
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 usesreturn
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.
- If you are not using
- 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.
- Example:
- 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
“…
- Examples: “Updates
- 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.”
- Example for
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 cd
ing 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.