Comparing Flask SQLAlchemy and Flask RESTful
Published: 2024-01-27 03:00:51



Comparing Flask SQLAlchemy and Flask RESTful
When I first started learning to code, I saw it as akin to learning a new language. Makes sense, right? After all, things like JavaScript, python, css, etc are literally called coding languages. However, as I have learned more about coding and written some code myself, I find it to be more akin to learning a craft like woodworking or sculpting. Sure, learning the individual syntax of a coding language is comparable to learning an actual language, but the way that code is implemented is less about learning how to express a thought the way a language would, and more about completing a task. 
Software development is building; it is crafting. The different methods and functions, tips, and tricks you pick up along the way of practicing coding are all the different tools in the developer toolkit. Adding even more flexibility to this tool analogy are extensions that can be added to a language to change it to suite your own comforts and practices. Take python for example. Funnily enough, I found python’s syntax already much easier to follow than, say, JavaScript. And yet it boasts a bevy of extensions designed to make coding much more comfortable and easier on the backend. Two popular extensions, Flask SQLAlchemy and Flask RESTful, serve different purposes but are commonly used together in building web APIs. In this article, we'll compare the pros and cons of each to help developers make informed decisions based on their project requirements.

Flask SQLAlchemy
Pros

```
@app.route('/save-team', methods=['POST', 'PATCH'])
def save_team():
    if request.method == "POST":
        data = request.get_json()

        # Retrieve the trainer ID from the session
        trainer_id = session.get("trainer_id")

        if trainer_id:
            new_team = Team(name=data['team_name'], trainer_id=trainer_id)
            db.session.add(new_team)
            db.session.commit()

            for pokemon_name in data['pokemon_names']:
                new_pokemon = Pokemon(name=pokemon_name)
                db.session.add(new_pokemon)
                db.session.commit()

                new_poketeam = PokeTeam(team_id=new_team.id, pokemon_id=new_pokemon.id)
                db.session.add(new_poketeam)

            try:
                db.session.commit()
                return jsonify(message='Team and Pokemon Created'), 201
            except Exception as e:
                db.session.rollback()
                return jsonify(error=str(e), message='An error occurred, please try again'), 500

    elif request.method == "PATCH":
        data = request.get_json()

        team_id = data.get('team_id')
        existing_team = Team.query.get(team_id)

        if not existing_team:
            return jsonify(error='Team not found'), 404

        if 'team_name' in data:
            existing_team.name = data['team_name']
            
        if 'pokemon_names' in data:
            existing_team.poke_teams = []

            for pokemon_name in data['pokemon_names']:
                existing_pokemon = Pokemon.query.filter_by(name=pokemon_name).first()

                if not existing_pokemon:
                    existing_pokemon = Pokemon(name=pokemon_name)
                    db.session.add(existing_pokemon)
                    db.session.flush()

                new_poketeam = PokeTeam(team_id=existing_team.id, pokemon_id=existing_pokemon.id)
                db.session.add(new_poketeam)
```

Function Flexibility: SQLAlchemy’s overarching benefit over RESTful api largely comes down to the customization that it allows developers to implement into the routes they create. While the routes may be longer to code than RESTful, the extra visible lines of code allow ease of access to go back into and augment said routes to add or alter functionality. Developers can write complex database queries using SQLAlchemy’s expressive API, empowering them to efficiently retrieve and manipulate data from the database.
ORM (Object-Relational Mapping): SQLAlchemy provides a powerful ORM tool that allows developers to interact with databases using Python objects. Flask SQLAlchemy seamlessly integrates with Flask, enabling developers to define database models as Python classes and perform database operations using Python syntax, which simplifies database interactions and reduces boilerplate code.
Database Agnostic: SQLAlchemy supports various database systems, including PostgreSQL, MySQL, SQLite, and others. Flask SQLAlchemy abstracts the differences between these databases, allowing developers to switch databases without significant code changes.
Migration Support: SQLAlchemy offers migration tools such as Alembic, which enable developers to manage database schema changes over time. Flask SQLAlchemy integrates seamlessly with Alembic, allowing developers to generate and apply database migrations effortlessly.
Integration with Flask: Flask SQLAlchemy is designed to work seamlessly with Flask, making it easy to incorporate SQLAlchemy into Flask applications. It provides built-in support for creating database sessions, committing transactions, and handling database errors within Flask routes.

Cons

Complexity: SQLAlchemy's biggest benefit also ties into its biggest flaw in comparison to RESTful api: complexity. While the more fleshed out, more spelled out nature of SQLAlchemy lends itself to higher levels of customization, that very explicit nature of how SQLAlchemy is written naturally makes it more complex. Developers may need to strike a balance between using SQLAlchemy's features and writing RESTful for optimal performance and simplicity.
Learning Curve: SQLAlchemy's ORM can have a steep learning curve for beginners due to its advanced features and concepts. Developers unfamiliar with ORMs may find it challenging to understand SQLAlchemy's querying syntax and ORM mapping conventions.

Flask RESTful
Pros

```
class PlantByID(Resource):

    def get(self, id):
        plant = Plant.query.filter_by(id=id).first().to_dict()
        return make_response(jsonify(plant), 200)

    def patch(self,id):
        record = Plant.query.filter_by(id=id).first()
        data = request.get_json()
        for attr in data:
            setattr(record, attr, data[attr])
        db.session.add(record)
        db.session.commit()
        return make_response(record.to_dict(),200)
    
    def delete(self,id):
        record = Plant.query.filter_by(id=id).first()
        db.session.add(record)
        db.session.commit()
        response_dict = {"message":"plant deleted"}
        return make_response(response_dict, 204)

api.add_resource(PlantByID, '/plants/<int:id>')
```
Streamlined Syntax: Flask RESTful follows a resource-oriented design approach, where resources are modeled as classes and mapped to HTTP methods (GET, POST, PUT, DELETE). This design promotes a clean and structured API architecture, making it easier to organize and manage endpoints for different resources. 
Unique to Flask RESTful is the concept of method view classes, where each HTTP method (GET, POST, PUT, DELETE) is implemented as a separate method within a class. This approach promotes code organization and readability, making it easier to understand and maintain API endpoints.
Content Negotiation: Flask RESTful supports content negotiation, allowing clients to specify their preferred response formats (JSON, XML, etc.) using HTTP headers. This feature enables developers to build APIs that can serve multiple response formats based on client preferences, enhancing interoperability and flexibility.
Integration with Flask: Flask RESTful is designed to seamlessly integrate with Flask, providing decorators such as serializers and validators to define RESTful endpoints within Flask applications. Developers can leverage Flask's existing features and extensions while building RESTful APIs, ensuring compatibility and ease of use.

Cons

Limited Built-in Features: As a counter to SQLAlchemy, while Flask RESTful provides essential features for building RESTful APIs, it may lack some advanced features found in other API frameworks. Developers may need to implement additional functionality or use third-party extensions to meet specific requirements, such as authentication, rate limiting, or pagination.
Learning Curve: Flask RESTful introduces additional concepts such as resources, request parsers, and method view classes, which may require some learning for developers new to building RESTful APIs. While these concepts promote a cleaner API design that can be quicker to code, they can add complexity for beginners.
Conclusion
Both Flask SQLAlchemy and Flask RESTful offer valuable features for building web applications and APIs with Flask. Flask SQLAlchemy simplifies database interactions and provides powerful ORM capabilities, while Flask RESTful promotes a clean and structured approach to building RESTful APIs.
When choosing between the two, developers should consider the requirements of their project, including the complexity of database operations, the desired API architecture, and the level of abstraction needed for handling HTTP requests and responses. Ultimately, the decision between Flask SQLAlchemy and Flask RESTful depends on factors such as project complexity, developer familiarity, and specific use case requirements.