A RESTful API (Representational State Transfer) is an architectural style for designing networked applications. It emphasizes a stateless client-server communication model, using standard HTTP methods (GET, POST, PUT, DELETE) to perform operations on resources identified by unique URLs. Key principles of REST include:
1. Stateless: Each request from client to server must contain all the information necessary to understand the request. The server should not store any client context between requests.
2. Client-Server: Separation of concerns allows client and server to evolve independently.
3. Cacheable: Responses can be cached to improve performance.
4. Layered System: A client cannot ordinarily tell whether it is connected directly to the end server or to an intermediary along the way.
5. Uniform Interface: Simplifies and decouples the architecture, typically achieved by:
- Resource Identification in Requests (e.g., `/books/123`)
- Resource Manipulation Through Representations (e.g., sending JSON/XML)
- Self-descriptive Messages (e.g., HTTP headers, status codes)
- Hypermedia as the Engine of Application State (HATEOAS - often the least implemented)
Flask-RESTful is an extension for Flask that provides a clean and concise way to build REST APIs. While Flask itself is a microframework and doesn't dictate how you build your APIs, Flask-RESTful adds a layer of abstraction that makes common patterns in API development much easier. It simplifies:
- Resource Management: By abstracting API resources into classes, allowing you to map HTTP methods (GET, POST, PUT, DELETE) directly to class methods.
- Request Parsing: Using `reqparse`, it provides a way to validate and parse arguments from requests, making sure your API receives the expected data.
- Response Handling: Automatically converts Python dictionaries and lists into JSON responses, simplifying data serialization.
- Routing: Integrates seamlessly with Flask's routing system but provides a higher-level API for defining endpoints and associated resources.
In essence, Flask-RESTful helps you focus on the logic of your API resources rather than boilerplate HTTP handling, making it an excellent choice for developing robust and maintainable RESTful services with Flask.
Example Code
from flask import Flask
from flask_restful import reqparse, abort, Api, Resource
app = Flask(__name__)
api = Api(app)
A simple in-memory 'database' for demonstration
TODOS = {
'todo1': {'task': 'build an API'},
'todo2': {'task': '?????'},
'todo3': {'task': 'profit!'},
}
def abort_if_todo_doesnt_exist(todo_id):
if todo_id not in TODOS:
abort(404, message=f"Todo {todo_id} doesn't exist")
Argument parser for POST and PUT requests
parser = reqparse.RequestParser()
parser.add_argument('task', type=str, required=True, help='Task is required', location='json')
Todo
shows a single todo item, and lets you delete them
class Todo(Resource):
def get(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
return TODOS[todo_id]
def delete(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
del TODOS[todo_id]
return '', 204 204 No Content
def put(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
args = parser.parse_args()
task = {'task': args['task']}
TODOS[todo_id] = task
return task, 200 200 OK
TodoList
shows a list of all todos, and lets you post new tasks
class TodoList(Resource):
def get(self):
return TODOS
def post(self):
args = parser.parse_args()
todo_id = 'todo%d' % (len(TODOS) + 1)
TODOS[todo_id] = {'task': args['task']}
return {todo_id: TODOS[todo_id]}, 201 201 Created
Actually setup the API resource routing
api.add_resource(TodoList, '/todos')
api.add_resource(Todo, '/todos/<string:todo_id>')
if __name__ == '__main__':
app.run(debug=True)
To run this code:
1. Save it as a Python file (e.g., app.py)
2. Install Flask and Flask-RESTful: pip install Flask Flask-RESTful
3. Run the application: python app.py
Example API calls using curl:
GET all todos: curl http://127.0.0.1:5000/todos
POST a new todo: curl -X POST -H "Content-Type: application/json" -d '{\"task\": \"learn Flask-RESTful\"}' http://127.0.0.1:5000/todos
GET a specific todo: curl http://127.0.0.1:5000/todos/todo1
PUT/update a todo: curl -X PUT -H "Content-Type: application/json" -d '{\"task\": \"rebuild API with new features\"}' http://127.0.0.1:5000/todos/todo1
DELETE a todo: curl -X DELETE http://127.0.0.1:5000/todos/todo2








RESTful API with Flask-RESTful