Skip to content

Migrating from Flask-RESTPlus or Flask-RESTX

Flask-RESTPlus is an extension for Flask that adds support for quickly building REST APIs. It is no longer maintained and has been superseded by Flask-RESTX.

APIFlask and Flask-RESTPlus/Flask-RESTx share similar goals and features, but the implementation is different. This guide will help you migrate from Flask-RESTPlus/Flask-RESTX to APIFlask.

Initialization

from flask import Flask
from flask_restx import Api

app = Flask(__name__)
api = Api(app)

Or:

from flask import Flask
from flask_restx import Api

api = Api()

app = Flask(__name__)
api.init_app(app)
from apiflask import APIFlask

app = APIFlask(__name__)

Routing

from flask import Flask
from flask_restx import Resource, Api

app = Flask(__name__)
api = Api(app)


@api.route('/hello')
class HelloWorld(Resource):
    def get(self):
        return {'message': 'Hello world'}
from apiflask import APIFlask

app = APIFlask(__name__)


@app.get('/hello')
def hello_world():
    return {'message': 'Hello world!'}

or:

from apiflask import APIFlask
from flask.views import MethodView

app = APIFlask(__name__)


class HelloWorld(MethodView):
    def get(self):
        return {'message': 'Hello world!'}

app.add_url_rule('/hello', view_func=Hello.as_view('hello'))

Response Formatting/Marshalling

Flask-RESTPlus uses the api.model to create a model and uses marshal_with decorator for response formatting.

from flask_restplus import fields, marshal_with

user_fields = api.model('User', {
    'name': fields.String,
    'age': fields.Integer
})

@api.route('/users')
class User(Resource):
    @marshal_with(user_fields)
    def get(self):
        return {'name': 'John', 'age': 30}

APIFlask uses marshmallow to define data schema and uses app.output for response formatting.

from apiflask import Schema
from apiflask.fields import Integer, String

class User(Schema):
    name = String()
    age = Integer()

@app.get('/users')
@app.output(User)
def get_user():
    return {'name': 'John', 'age': 30}

You can also import the Schema, Integer, and String from marshmallow directly.

Request Parsing / Argument Parsing

Flask-RESTPlus uses the built-in reqparse module for request parsing.

from flask_restplus import reqparse

parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True)
parser.add_argument('age', type=int, required=True)
args = parser.parse_args()

But the reqparse module is deprecated and will be removed in the future version.

Besides, you can also use api.expect with API model for request parsing.

from flask_restplus import fields, marshal_with

user_fields = api.model('User', {
    'name': fields.String,
    'age': fields.Integer
})

@api.route('/users')
class User(Resource):
    @api.expect(user_fields)
    def post(self):
        pass

APIFlask uses marshmallow to define data schema and uses api.input for request parsing.

from apiflask import Schema
from apiflask.fields import Integer, String

class User(Schema):
    name = String(required=True)
    age = Integer(required=True)

@app.get('/')
@app.input(User, location='json')
def create_user(json_data):  # the arg name defaults to the `<location_name>_data`
    pass

You can also import the Schema, Integer, and String from marshmallow directly.

Error Handling

Flask-RESTPlus automatically handles errors and returns a JSON response with the error message.

{
    "message": "The browser (or proxy) sent a request that this server could not understand."
}

To add custom error data, you can add data attribute to the exception or use the flask_restplus.abort method.

from flask_restplus import abort
abort(400, custom='value')

output:

{
    "message": "The browser (or proxy) sent a request that this server could not understand.",
    "custom": "value"
}

To document the error response, you can use the :raises annotation in the docstring.

@api.route('/test/')
class TestResource(Resource):
    def get(self):
        '''
        Do something

        :raises CustomException: In case of something
        '''
        pass

APIFlask also automatically handles errors and returns a JSON response with the error message.

{
    "message": "The browser (or proxy) sent a request that this server could not understand.",
    "detail": {}
}

To add custom fields, define a custom exception class that inherits from HTTPException:

from apiflask import HTTPError

class PetNotFound(HTTPError):
    status_code = 404
    message = 'This pet is missing.'
    extra_data = {
        'error_code': '2323',
        'error_docs': 'https://example.com/docs/missing'
    }

or use apiflask.abort with extra_data argument:

abort(
    400,
    message='Something is wrong...',
    extra_data={
        'docs': 'http://example.com',
        'error_code': 1234
    }
)

output:

{
    "message": "Something is wrong...",
    "detail": {},
    "docs": "http://example.com",
    "error_code": 1234
}

To document the error response, you can use the app.doc decorator:

@app.get('/')
@app.doc(responses=[400])
def hello():
    return 'Hello'

OpenAPI (f.k.a Swagger) Documentation

For Flask-RESTPlus/Flask-RESTX, the default OpenAPI spec is available at /swagger.json, and the Swagger UI is available at the API root /.

For APIFlask, the default OpenAPI spec is available at /openapi.json, and the Swagger UI or other alternative UIs is available at /docs.

To collect the API documentation, they provide similar APIs, see the following table for the details:

Flask-RESTPlus/Flask-RESTX APIFlask
@api.doc() @app.doc()
@api.marshal_with() @app.output()
@api.expect() @app.input()
@api.responses() @app.doc(responses=...)
@api.deprecated @app.doc(deprecated=True)
@api.hide @app.doc(hide=True)

They also use the similar way to define the basic settings of the API documentation:

Flask-RESTPlus/Flask-RESTX:

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
api = Api(app, version='1.0', title='Sample API', description='A sample API')

APIFlask:

app = APIFlask(__name__, version='1.0', title='Sample API', description='A sample API')

But APIFlask provides extensive configuration options for the API documentation.

Postman Support & Field Masks

Flask-RESTPlus provides a built-in feature to generate Postman collections:

from flask import json

from myapp import api

urlvars = False  # Build query strings in URLs
swagger = True  # Export Swagger specifications
data = api.as_postman(urlvars=urlvars, swagger=swagger)
print(json.dumps(data))

It also supports partial object fetching (aka. fields mask) by supplying a custom header in the request.

APIFlask does not provide these features yet. Create an feature request if you need it.