I have a web application which is backed by REST API located on the same server. Let's say I have a Task
resource accessible on /api/task/<task_id>
and a web page /create-task
which is basically just a form to create a task. There are several ways how to do it:
a) Communicate with REST API using Javascript (don't want to do that)
b) Create object directly in a database
@app.route('/create-task', methods=['POST'])
def create_task(self):
# create an object
try:
task = Task(request.form)
except:
# handle errors and put them to form
pass
# save it into db
task.save()
c) call REST API using requests
library
@app.route('/create-task', methods=['POST'])
def create_task(self):
# send request to REST API
r = requests.post(url_for('api.task', _external=True), json=request.form.data)
if r.status_code != 200:
# handle errors and put them to form
pass
What option would you consider to be the best practice? Think of issues associated with error handling and forms.
Bonus question concerning flask-restful
. Let's say I have already a working API built with flask-restful and want to use option b). Can I somehow use TaskResource.post
to do that?
If possible, the actual best thing to do would be to call the API code directly through Python without going through HTTP and REST. This would avoid the overhead and possible failure points of a HTTP request. I'm not familiar with flask-restful
so I don't know how easy this might be. The answer in "Calling flask restful API resource methods" seems to suggest just extracting the common code from the API to a library you can use in both the API and your app, which would work too.
Other than that:
A) using Javascript/AJAX might not be too bad if the API doesn't require authentication or isn't meant to be "secret". You'd have to write form error-handling in Javascript but you can avoid the HTTP request to /create-task if the REST API call returns an error.
C) is better than B) because there's less possibility for things breaking. Only the REST API is responsible for creating tasks and all you're doing is passing parameters. The problem is you would need to read out any error responses from the API and re-write them in your form handler, which is dumb work. Also this creates fragility in being able to generate proper URL in url_for('api.task')
, being able to access that URL on production servers, and so on.
B) is bad for the same reason copy-pasting code is bad. You now have two places where tasks are created and you have to remember to modify both if changing something (e.g. database implementation details). This will eventually break and come back to hurt you.