helloworld1234
helloworld1234

Reputation: 327

Python Flask calling different version API

I'm new to Python Flask, I'm having an issue with versioning API design. Consider the URL to perform the GET method to the user API.

v1 - <URL>/api/v1/users?q=getUserInfo?name=ryan
v2 - <URL>/api/v2/users?q=getUserInfo?name=ryan&gender=male

While 'user' API in v1 and v2 might have a different implementation in the development period, the client will call a different version of API for different requests and API responds differently according to API call. How should I route the client to the respective version of the API while the user calls the different API?

Here is my server.py:

from flask import Flask, request
import sys
sys.path.insert(0, '../api')
app = Flask(__name__)

@app.route('/api/<version>/<api>/<action>')
def api(version, api, action):
    # How should I call my API and get return data to the client?
    return json.dumps(return_info)  

if __name__ == '__main__':
    app.run(debug=True, host='127.0.0.1', port='8081')

In my api/v1/user.py

def getUserInfo(name):
    # some logic and return user info

In my api/v2/user.py

def getUserInfo(name, gender):
    # some logic and return user info

The basic idea is the server.py act as the central route to a different version of API based on the client's request and response to the client.

Besides, API in different version contains multiple .py files for modular design, for example: <version>/product.py API handles request for product, <version>/cart.py API handles request for cart, etc.

So the question is, how should I call to my different version of API file and return the response to the client?

Upvotes: 2

Views: 3850

Answers (1)

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Note, its not obligatory to have versioning for all resources.
When we support a different versions of endpoints within a single server node (or microservice) - we are usually call them "coexisting endpoints".
If you decide to pass an API version as dynamic request param <version> you have to implement a custom dispatcher to load/apply a different handler for each version.
A much easier way to support coexisting endpoints is to register different routes for each version.
While Sanic server allows to pass the version keyword to the route decorators, or to a blueprint initializer, in Flask you could apply simple blueprints:

...
# import <needed_features> from api/v1/user.py
# import <needed_features> from api/v2/user.py
...

bp_api_v1 = Blueprint('api_v1', __name__, url_prefix='/api/v1')
bp_api_v2 = Blueprint('api_v2', __name__, url_prefix='/api/v2')

app.register_blueprint(bp_api_v1)
app.register_blueprint(bp_api_v2)

@bp_api_v1.route('/users/<action>')
def api(request, action):
    # call getUserInfo from api/v1/user.py
    user_info = getUserInfo(request.args.get('name'))
    return json.dumps(user_info)    


@bp_api_v2.route('/users/<action>')
def api(request, action):
    # call getUserInfo from api/v2/user.py
    user_info = getUserInfo(request.args.get('name'))
    return json.dumps(user_info)    

Upvotes: 2

Related Questions