Codementor Events

Building a RESTful Blog APIs using python and flask - Part 2

Published Jul 28, 2018Last updated Jan 24, 2019

Building a RESTful Blog APIs using python and flask - Part 2

To be a programmer is to develop a carefully managed relationship with error. There's no getting around it. You either make your accommodations with failure, or the work will become intolerable - Ellen Ullman

Summary From Part 1

In part 1, we covered how to create a simple RESTful API with four basic CRUD operation and Authentication using Flask. We learned about configuring Flask environment, creating models, making and applying migrations to the DB, grouping resources using flask blueprint, validating the authenticity of a user using JWT token.

In this part, we will build the remaining four endpoints for blogpost resource

Blogpost API

The following endpoints will be created

  • Create a Blogpost - POST api/v1/blogposts
  • Get All Blogposts - GET api/v1/blogposts
  • Get A Blogposts - GET api/v1/blogposts/<int:blogpost_id>
  • Update A Blogpost - PUT api/v1/blogposts/<int:blogpost_id>
  • Delete A Blogpost - DELETE api/v1/blogposts/<int:blogpost_id>

Create a Blogpost - POST api/v1/blogposts

Open /src/views/BlogpostView.py and add the following code

alt

In the above code, we added a new endpoint POST /api/v1/blogpost that would allow a user to create a new blogpost. Noticed with added @Auth.auth_required decorator to create() function to make sure only authenticated users can access the route. We also set up blogpost_api blueprint so that we can group all blogpost endpoints in the same resource.

Let's test this endpoint on postman

Screen Shot 2018-07-28 at 2.38.00 PM.png

Don't forget to add api-token to the header since we are only permitting registered users to create a post

Get All Blogposts - GET api/v1/blogposts

Get all blogpost endpoint will get all available blogpost in the system
Let's add a new function to /src/views/BlogpostView.py and call it get_all

alt

You'll notice we did not add @Auth.auth_required decorator to get_all, that is because we want to make that endpoint available to everybody - of course, you don't want to be the only one to read your posts 😃.

Test on postman

Screen Shot 2018-07-28 at 2.39.43 PM.png

Get A Blogpost - GET api/v1/blogposts/<int:blogpost_id>

This endpoint will get a single blogpost by it's id. Just like Get all endpoint, we'll also make this available for everybody - registered users or unregistered users.

alt

Test on postman

Screen Shot 2018-07-28 at 2.40.34 PM.png

Update A Blogpost - PUT api/v1/blogposts/<int:blogpost_id>

Something to note before we create this endpoint

  • Only registered users can access this endpoint
  • Users can only update their own blogpost
  • A user can not update another user's blogpost
    To do this, let's create a new function and add @Auth.auth_required decorator and also add a condition that checks if the post owner_id is equal to the current user's id. If the owner_id is equal to user_id then go ahead and update the post, if not return an error back to the user

alt

Test on postman

Screen Shot 2018-07-28 at 2.41.25 PM.png

Delete A Blogpost - DELETE api/v1/blogposts/<int:blogpost_id>

This endpoint will allow a user to delete only their own post - meaning a user cannot delete another user's post.

alt

Test on postman

Screen Shot 2018-07-28 at 2.42.04 PM.png

CONCLUSION

This part covers the creation of create, get all, get one, update and delete endpoints. We make get all and get one endpoints accessible to everyone and also added condition to delete and update endpoints so that a user can only update or delete their own post.

In part 3 of this series, we'll write unit test for our app and also host the app on heroku - you can call it 2 in 1 pack.

Click here if you haven't read PART 1

Click here to checkout the complete code on Github

Drop you questions, comment and don't forget to like this post if you learned one or two things from it

Discover and read more posts from Olawale Aladeusi
get started
post commentsBe the first to share your opinion
Jericho Ruz
3 years ago

Same project, but with some improvements and with paypal service and email notifications https://github.com/jerichoruz/backbloggie

Jericho Ruz
4 years ago

Once again Thank u very much Olawale . as for sept 2020 remember that the last version of sqlalchemy uses marshmallow 3

Changed in version 3.0.0b7: This method returns the deserialized data rather than a (data, errors) duple. A ValidationError is raised if invalid data are passed.

Change all the:
data, error = blogpost_schema.load(req_data)
to:

try:
data = blogpost_schema.load(req_data, partial=True)
except ValidationError as err:
return custom_response(err, 400)

and
data = blogpost_schema.dump(post).data
to:
data = blogpost_schema.dump(post)

to avoid
Python (flask/ marshmallow)ValueError: too many values to unpack (expected 2)

Nishant Ranjan
5 years ago

Nice and well explained. Keep it up. Thanks, Nishant

Show more replies