I intend this document to clarify some of the aspects of designing the backend API for StudyJam. The API design is simple (and probably incomplete). There is also no notion of authentication, which should definitely be a concern.
A GET
request to each URL will return JSON appropriate
to the information requested.
Request:
GET /api/user/<int:id> HTTP/1.1
Result:
{
"name": "Andy",
"study_level": 3,
}
Request:
GET /api/user/<int:id>/location HTTP/1.1
Result:
{
"latitude": 34.097890,
"longitude": -117.712412,
}
Request:
GET /api/user/<int:id>/friends HTTP/1.1
Result:
{
"friends": [
{
"id": 123,
"name": "Mauricio",
},
{
"id": 456,
"name": "Parth",
}
]
}
POST
ing to any of these URLs will instead modify the data on the server.
To send new information to the server, we can write a simple HTML form that
POST
s to the URL. Sending a POST
from the phone will work the same way, so
we can use the same code for each. Here's a form (Flask template) that should do
the trick. Ensure that you pass in a user_id
when you render the form.
<html>
<body>
<form name="location" action="{{ url_for('get_user_location', user_id ) }}" method="post">
<div>
<label for="latitude">Latitude:</label>
<input required type="text" name="latitude">
</div>
<div>
<label for="longitude">Longitude:</label>
<input required type="text" name="longitude">
</div>
<input type="submit" value="POST">
</form>
</body>
</html>
When the submit button is clicked, the browser will send a post request to the appropriate URL, with the form information encoded in the request.
Request:
POST /api/user/<int:user_id>/location HTTP/1.1
latitude=34.101826&longitude=-117.712648
Result:
The server will store the new location in the user with id user_id
.
What's great about Flask is that you don't have to parse any of the requests
yourself. Implementing get_user_location()
might look like this:
from flask import request # etc...
import json
@app.route('/api/user/<int:user_id>/location', methods=['GET', 'POST'])
def get_user_location(user_id):
if request.method == 'POST':
# Pull the info we need out of the request
latitude = request.form['latitude']
longitude = request.form['longitude']
if latitude and longitude:
# Now we create the part of the object that needs to be updated
new_location = { 'latitude': latitude, 'longitude': longitude }
# update_user_location() modifies the information in the document in storage
update_user_location(user_id, new_location)
# get_user_location() returns a user location object from storage
return json.dumps(get_user_location(user_id))
Note that we can send both GET
and POST
requests to this URL.
Note that the <form>
element has a method="post"
attribute. This makes the
browser encode the form information into the request. We can also make the form
have method="get"
instead. This will make the browser encode the information
into the URL. That is, the request would look like this:
GET /api/user/<int:user_id>/location#latitude=34.101826&longitude=-117.712648 HTTP/1.1
You can access these URL parameters in Flask like so:
# Use None as a default in case there are parameters missing
latitude = request.args.get('latitude', None)
longitude = request.args.get('longitude', None)
The convention is to use POST
when changing state on the server, and to use
GET
when you are only reading state.
Hopefully this helps! Let me know if if anything is unclear.