Tutorial: Chatter Backend
Cover Page
DUE Wed, 09/10, 2 pm
We will build on the backend server you created in the previous tutorial. If you haven’t created a server, please create one according to the instructions in the previous tutorial. All subsequent tutorials and projects in this course require access to a backend server as set up in these two tutorials. Instead of setting a separate server for each assignment, you may want to keep your server up and running for the duration of the term.
Install updates
Remember to install updates available to your Ubuntu back end. If N in the following notice you see when you ssh to your back-end server is not 0,
N updates can be applied immediately.
run the following:
server$ sudo apt update
server$ sudo apt upgrade
Failure to update your packages could lead to your solution not performing at all, without any warning that it is due to outdated packages, and also makes you vulnerable to security hacks.
Any time you see *** System restart required *** when you ssh to your server, immediately run:
server$ sync
server$ sudo reboot
Your ssh session will be ended at the server. Wait a few minutes for the system to reboot before you ssh to your server again.
PostgreSQL
We will be using the PostgreSQL relational database management system (RDBMS) to store chatts posted by the frontend and, later, to store responses returned by LLM as history/context for subsequent prompts.
First install PostgreSQL:
server$ sudo apt install libpq-dev postgresql postgresql-contrib
Once PostgreSQL is installed:,
- Log into an interactive Postgres (
psql) session as userpostgres:server$ sudo -u postgres psqlYou may receive the message: “could not change directory to “/root”: Permission denied”. You can safely ignore this message.
Your command-line prompt should now change to
postgres=#. - Check the version of your PostgreSQL:
SELECT version();It should say version 13 or higher. Consult the teaching staff if it doesn’t.
- Create a database user for your project. Make sure to select a secure password.
CREATE USER chatter WITH PASSWORD 'chattchatt';
TIP: Forgetting to do this is a common cause of getting
HTTP error code 500 Internal Server Error.All SQL commands must end with a
;. - Create a database for your project and change its owner to
chatter:CREATE DATABASE chatterdb; ALTER DATABASE chatterdb OWNER TO chatter; - Connect to the database you just created:
\connect chatterdb\connectmay be shortened to\c.Your command-line prompt should now change to
chatterdb=#. - Next use SQL command to create a
chattstable in thechatterdbdatabase. The table consists of four columns:username,message,id, andtime:CREATE TABLE chatts (username VARCHAR(100) NOT NULL, message TEXT NOT NULL, id UUID NOT NULL, time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP(0));We will generate a random UUID as the
idof each entry;timewill be automatically filled in by the database when an entry is inserted. - Give user
chatteraccess to administer the new database, including querying and inserting new data:GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO chatter; - Insert and view a sample entry:
INSERT INTO chatts VALUES ('testuser1', 'Hello world', gen_random_uuid()); SELECT * from chatts;You should see something like:
username | message | id | time | -----------+-------------+--------------------------------------+----------------------------| testuser1 | Hello world | 20f713af-015d-48c8-8b09-3036cf104134 | 2025-01-03 10:54:58.362108 | (1 row)
TIP: Trying to send a usernamelonger than 100 characters will also result in HTTP error code500 Internal Server Error. - To delete all entries from a table:
TRUNCATE TABLE chatts; - You can issue the
\dtcommand to list all tables in your database:\dt List of relations Schema | Name | Type | Owner --------+--------+-------+---------- public | chatts | table | postgres (1 rows)and
\d <tablename>to list the schema of a table:\d chatts Table "public.chatts" Column | Type | Collation | Nullable | Default ----------+--------------------------+-----------+----------+---------------------- username | character varying(100) | | not null | message | text | | not null | id | uuid | | not null | time | timestamp with time zone | | | CURRENT_TIMESTAMP(0) - When you are finished, exit PostgreSQL:
\qor hit
Ctl-d(^d).
Add PostgreSQL as chatterd’s dependency
To ensure PostgreSQL is running when chatterd runs, edit chatterd’s service configuration file:
server$ sudo vi /etc/systemd/system/chatterd.service
Update the [Unit] block to say:
[Unit]
Description=EECS Reactive chatterd
Requires=postgresql.service
After=network.target
StartLimitIntervalSec=0
Then reload chatterd’s configuration to systemctl and restart chatterd:
server$ sudo systemctl daemon-reload
server$ sudo systemctl restart chatterd
chatterd
Please click the relevant link to setup the chatterd server with the
Chatter APIs using the web framework of your choice:
Go | Python | Rust | TypeScript
and return here to resume the server setup once you have your web framework set up.
Switching back-end stack
To switch back-end stack, you do not need to set up a new AWS/GCP server, you can re-use the same server. You can also re-use your public key certificate and private key. All of the back-end alternatives assume the same file locations for these. You do not need to move them. All aletrnatives also work with the same PostgreSQL set up. You can re-use your existing chatterdb PostgreSQL database and chatts table. But you would need to set up the alternate back-end stack you want to switch to from scratch, following the chatter tutorial back-end spec starting from the Web server framework section to the end of the spec before continuing with the steps below.
In particular, should you decide to switch from a Go/Rust backend to a JavaScript or Python backend, or vice versa, update your /etc/systemd/system/chatterd.service file to point to the new back-end server and do:
server$ sudo systemctl daemon-reload
server$ sudo systemctl restart chatterd
You don’t need to edit the chatterd.service file but only need to restart chatterd if you’re switching between Go and Rust backends. See the Chatter tutorial spec for instructions on how to edit the chatterd.service.
Testing Chatter APIs
with Postman on desktop
Assuming you have set up your Postman for HTTP/2 with disabled SSL certificate validation as in the previous tutorial:
-
Create a new request in Postman to
POSTtohttps://YOUR_SERVER_IP/postchatt/withBody > raw > JSON:{ "username": "Postman", "message": "Ring! Ring!" }and click the big blue
Sendbutton.If everything works as expected, the bottom pane of Postman should say, to the right of its menu line,
Status: 200 OKand the pane should simply display{}. -
You can create a new request in Postman to do
GETfromhttps://YOUR_SERVER_IP/getchattsand click the big blueSendbutton. It should return something like:[ [ "Postman", "Ring! Ring!", "9249b958-6e46-44b2-8004-9bccf0e8f1c1", "2022-07-22T17:33:25.947" ] ]
with a command-line tool
curl
To test HTTP POST (or HTTP PUT or other) requests with curl:
laptop$ curl -X POST -d '{ "username": "Curly", "message": "Hello World" }' --insecure https://YOUR_SERVER_IP/postchatt/
The --insecure option tells curl not to verify your self-signed certificate.
To retrieve the posted chatt:
laptop$ curl --insecure https://YOUR_SERVER_IP/getchatts/
HTTPie
To test HTTP POST with HTTPie:
laptop$ echo '{ "username": "weepie", "message": "Yummy!" }' | http --verify=no POST https://YOUR_SERVER_IP/postchatt/
# output:
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 2
Content-Type: application/json
Date: Wed, 22 Jul 2022 17:45:53 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{}
The --verify=no option tells HTTPie not to verify your self-signed certificate.
To retrieve the posted chatt with HTTPie:
laptop$ http --verify=no https://YOUR_SERVER_IP/getchatts/
# output:
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 116
Content-Type: application/json
Date: Wed, 22 Jul 2022 17:46:32 GMT
Server: nginx/1.14.0 (Ubuntu)
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
[
[
"weepie",
"Yummy!",
"d6e5f8a6-e3cc-4501-9359-517af9f64cda",
"20242-07-22T17:45:53.177"
]
]
WARNING: You will not get full credit if your front end is not set up to work with your backend!
Everytime you rebuild your Go or Rust server or make changes to either of your JavaScript or Python files, you need to restart chatterd:
server$ sudo systemctl restart chatterd
Leave your chatterd running until you have received your tutorial grade.
TIP:
server$ sudo systemctl status chatterd
is your BEST FRIEND in debugging your server. If you get an HTTP error code 500 Internal Server Error or if you just don’t know whether your HTTP request has made it to the server, first thing you do is run sudo systemctl status chatterd on your server and study its output.
If you’re running a Python server, it also shows error messages from your Python code, including any debug printouts from your code. The command systemctl status chatterd is by far the most useful go-to tool to diagnose your back-end server problem.
That’s all we need to do to prepare the back end. Before you return to work on your front end, wrap up your work here by submitting your files to GitHub.
Submitting your back end
We will only grade files committed to the main branch. If you use multiple branches, please merge them all to the main branch for submission.
Navigate to your reactive folder:
server$ cd ~/reactive/
Commit changes to the local repo:
server$ git commit -am "chatter back end"
and push your chatterd folder to the remote GitHub repo:
server$ git push
If git push failed due to changes made to the remote repo by your tutorial partner, you must run git pull first. Then you may have to resolve any conflicts before you can git push again.
Go to the GitHub website to confirm that your back-end files have been uploaded to your GitHub repo.
References
| Prepared by Tiberiu Vilcu, Wendan Jiang, Alexander Wu, Benjamin Brengman, Ollie Elmgren, Luke Wassink, Mark Wassink, Nowrin Mohamed, Chenglin Li, Xin Jie ‘Joyce’ Liu, Yibo Pi, and Sugih Jamin | Last updated August 25th, 2025 |