Assignment 4: Bitter
Due: 5pm, Thursday, March 13. Value: 50 pts. You may work with one other student on this assignment if you wish.
In this assignment, you'll develop a Web server for a Twitter knock-off named Bitter, where users post beets complaining about life, and where other users can subscribe to other users' beet feeds. The server will rely upon SQLite to store information about the users and their beets.
Browser-side implementation
A browser-side implementation, developed in HTML, CSS, and JavaScript is already prepared for you in the following files.
main.html | the HTML and CSS necessary for the page. |
bitter-client.js | the JavaScript (using jQuery) that talks to the server. |
jquery-1.11.0.min.js | the jQuery library that the browser depends upon. |
You should not modify any of these files as part of this assignment.
Server-side setup
You probably still have Node.js installed along with the packages downloaded with the npm commands, done as Steps 1 and 2 in Assignment 2; but if not, you will need to do so.
Into the directory where you will do your work for this assignment, download the three files named above that are part of the browser-side implementation as well as two more files:
bitter-init.sql Contains SQL for configuring an initial SQLite database. bitter-server.js Contains skeleton Node.js code for a server. At the command line in that same directory, execute the command “
sqlite3 beets.db < bitter-init.sql
” to create the SQLite database, named beets.dbTo start the server, execute “
node bitter-server.js
”, which starts the server on port 8888 on your local computer. In a Web browser, you can load the page by navigating to localhost:8888.Whenever you finish editing the
bitter-server.js
file and are ready to test your modified version, you'll need to stop the server running by typing Ctrl-C (depress the Ctrl key, then type C, then release the Ctrl key). And then you'll restart it again using “node bitter-server.js
”.
Database
The database created using the SQL in bitter-init.sql
includes three tables.
users(login, passwd)
beets(beetid, login, message, posttime)
subscriptions(subscriber, feed)
It also creates three users.
Login ID Password Subscriptions bugs
bunny
elmer
,daffy
elmer
fudd
bugs
daffy
duck
bugs
AJAX requests
In addition to serving the browser-side files as downloaded,
your program should be able to respond to the following AJAX
requests that come from the Web browser.
All AJAX responses should be in JSON format, with an ok
field that is true
or false
depending on whether
the request is successful.
Possible causes of unsuccessful responses include problems in SQL
as reported by SQLite, or the failure conditions listed below.
If ok
is false
, an additional attribute message
provides more details about the problem, formatted to be
appropriate for display to the user.
If ok
is true
, some AJAX responses (namely /fetch
and /feeds
) will include additional data as
specified below.
/login
[Note: already implemented in handout code]-
HTTP request type: POST
HTTP request parameters:
login
,passwd
Failure condition: Login ID/password combination not found in database.
Action: None. This is just for confirming that login ID/password combination is valid.
/fetch
-
HTTP request type: POST
HTTP request parameters:
login
,passwd
Failure condition: Login ID/password combination not found in database
Action: Retrieves all beets in the database that belong to the user's feed or to one of the feeds to which the user has subscribed.
HTTP response data:
beets
, a list of objects representing beets; each beet includeslogin
,message
, andposttime
attributes. The beets should be in reverse order by post time, and the list should only contain beets that are either posted by the user or in feeds subscribed to by the user. /add
-
HTTP request type: POST
HTTP request parameters:
login
,passwd
,message
.Failure conditions:
- Login ID/password combination not found in database.
- Message contains more than 100 characters.
Action: Adds a new beet into the user's feed. (Note that you need not specify
beetid
orposttime
; both will default to appropriate values.) /feeds
-
HTTP request type: POST
HTTP request parameters:
login
,passwd
.Failure condition: Login ID/password combination not found in database.
Action: Retrieves a list of all users' login IDs along with an indicator of whether the logged-in user has subscribed to that user's feed.
HTTP response data:
feeds
, a list of objects representing users; each user object includeslogin
andsubscribed
attributes. The beets should be in alphabetical order by login ID. Thesubscribed
attribute should be 0 or 1 indicating whether the user has subscribed to that user's feed. /subscribe
-
HTTP request type: POST
HTTP request parameters:
login
,passwd
,feed
.Failure conditions:
- Login ID/password combination not found in database.
- Requested feed does not exist among users.
- User is already subscribed to the feed.
Action: Modifies the database to reflect that the user has subscribed to the requested feed.
/unsubscribe
-
HTTP request type: POST
HTTP request parameters:
login
,passwd
,feed
Failure conditions:
- Login ID/password combination not found in database.
- Requested feed does not exist among users.
- User is already not subscribed to the feed.
Action: Modifies the database to reflect that the user is no longer subscribed to the requested feed.
/register
-
HTTP request type: POST
HTTP request parameters:
login
,passwd
Failure conditions:
- Login ID or password is more than 10 characters long.
- Login ID or password is empty.
- Login ID contains characters that are not letters or
digits. (To test this, I recommend
“
if (!/^[a-z0-9]+$/.test(login))
”.) - Login ID is already in the database.
Action: Adds a new user into the database.
Most AJAX requests (all but
/register
) involve confirming whether the login ID/password combination is valid. The distributed code includes a functionconfirmLogin
that I strongly recommend that you use for this. Its final argument is a function that is called only if the ID/password combination is valid.I suggest breaking this assignment into steps, fully implementing and testing your solution before going on to the next step. Here are the steps I would recommend, ordered by estimated difficulty.
Implement
/fetch
and/add
.Implement
/feeds
and/subscribe
.Implement
/unsubscribe
and/register
.
Please be sure to test the failure conditions! In some cases, the most straightforward way to test the condition may be to edit the database while the server is running. For example, to test
/subscribe
's failure condition 3, you may want to load the list of feeds in your browser, then in a terminal window open up SQLite to add a subscription, then try to add the same subscription via the browser to confirm that an error results.