Calling REST API from the same server

Marigold picture Marigold · Nov 11, 2014 · Viewed 12.9k times · Source

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?

Answer

Jarek Pi&#243;rkowski picture Jarek Piórkowski · Nov 13, 2014

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.