How To Build A User Crud Api With Authorization, Authentication, Validation Anad Some Other Bonuses
CRUD API
Table of contents
No headings in the article.
Creating a crud API involves a lot of steps. However, for this article, I'm going to be using the Django rest framework.
STEP 1
Create a new directory called user API. you can create a new directory by using the command mkdir user API
C:\Users\USER> mkdir userApi
Once this is done you should move into the directory, you do this by inputting the command C:\Users\USER> cd user API
STEP 2
The next thing that you are going to do is to install your virtual environment. As you can clearly remember from my previous article, you can have as many virtual environments as you like. One for each project or program you run.
To do this, you are going to type in the comment below
virtualenv (name of your virtual environment)
In my case virtualenv userApi
So after doing that, your venv (virtual environment ) should be successfully installed. In case you don't have it installed you can install it by running the following command on your terminal
pip install virtualenv v(name of your virtual environment)
Once that is done, all you need to do is to activate your virtual environment. Like I said earlier if it isn't activated it is more or less like an ordinary directory.
To activate it, run the following command on your terminal
Scripts/activate.bat
NOTE:This is for Windows users only
For macbook users
source\bin\activate
Never intended to post this, I'm just giving this out as a bonus to other aspiring programmers out there, to enable you to solve this easily on your own
If your venv has been activated you should see it like this
This is the evidence of your activated venv
(vmusic)
This is the name of one of my venv that I used for one of my projects
STEP 3
The next thing to do is to download your Django app on some terminal, for those who don't know how to do this. Not to worry I have got you covered.
This is how you do this
pip install djangorestframework
Once that is done, you should see something like this on your terminal
(vmusic) C:\Users\USER\vmusic> pip install django pillow
Collecting django
Using cached Django-3.2.16-py3-none-any.whl (7.9 MB)
Collecting sqlparse>=0.2.2
Using cached sqlparse-0.4.3-py3-none-any.whl (42 kB)
Collecting pytz
Using cached pytz-2022.6-py2.py3-none-any.whl (498 kB)
Collecting asgiref<4,>=3.3.2
Using cached asgiref-3.4.1-py3-none-any.whl (25 kB)
Collecting typing-extensions
Using cached typing_extensions-4.1.1-py3-none-any.whl (26 kB)
Installing collected packages: typing-extensions, sqlparse, pytz, asgiref, pillow, django
Successfully installed asgiref-3.4.1 django-3.2.16 pillow-8.4.0 pytz-2022.6 sqlparse-0.4.3 typing-extensions-4.1.1
This shows that you have successfully installed the Djangorestframework, the other app that was downloaded is needed for the Django app to run
STEP 4
The next step just requires you to start your project. Before I show you how to start your project I would like to enlighten you on some of the consequences of not starting your project
Firstly, your server will not run, even though you have successfully downloaded the Django app it would all be in vain.
Your project can only run in the manage.py dir of your project, so if you don't start your project will again not run.
You will keep on getting the error no such dir exists. In truth, this is true because you didn't start your project.
Now why am I telling you all of this, you might find this insignificant but I am still taking the time to tell you this to enable you to avoid countless error
Below is the code for starting your project
django-admin startproject (name of your project)
The next thing to do is to move into the dir of your project
(vmusic) C:\Users\USER\vmusic> cd MusicPlayer cd (name of your project)
If you have successfully done that you see this
(vmusic) C:\Users\USER\vmusic\MusicPlayer>
STEP 5
You can now run your server that you are in the manage.py dir. The code for this is :
(vmusic) C:\Users\USER\vmusic\MusicPlayer> python manage.py runserver
Once it is run you should get this as a result
Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. December 07, 2022 - 15:26:24 Django version 3.2.16, using settings 'MusicPlayer.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK
Now that you have run your server you can now copy your server link and paste it on any of your web browsers to further verify if you have successfully downloaded the Django app.
It should give you this, if successfullyStep 6
The next thing to do is to create your app by running the command Django-admin startapp ( name of your app )After that, you do not necessarily need to move into the app directory. The next big step starts now, you are now going to import your project into any of your text editors.
In my case I used the sublime text editor, you can also use that or any other text editor of your choice.
The pic below shows the list of your registered apps, this is where you will register your app.
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'crud_api', 'rest_framework' ]
As you can see the name written as note_api and rest_framework are the registered app, any app which you download on your terminal should be registered there.
In this section, you are now going to create a database model that the API will use to perform the crud operations and a serializer model that the Djangorest framework will use to convert the models into serialized JSON models.
So you are now going to create a new file in your crud_api dir, you are goin to call it models.py. Once done copy and paste the following code to it.
import uuid
from django.db import models
class NoteModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=255, unique=True)
content = models.TextField()
category = models.CharField(max_length=100, null=True, blank=True)
createdAt = models.DateTimeField(auto_now_add=True)
updatedAt = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = "notes"
ordering = ['-createdAt']
def __str__(self) -> str:
return self.title
The model. The UUID field will tell DJANGO TO GENERATE A UUID FOIR THE ID FIELD BY EVOKINGG THE UUID FUNCTION
We also added a unique constraint to the title field to ensure that no two records in the table end up with the same title.
STEP 7
In the crud-api directory yoyu are going to create a new file called serializer.py, after ddoing that ad the following code to it.
from rest_framework import serializers
from crud_api.models import NoteModel
class credentialsSerializer(serializers.ModelSerializer):
class Meta:
model = credentialsModel
fields = '__all__'
The code pasted above will automically generate a set of field for the credentials serillizers and it will also automatically generate validators for the serialaizers.
The next thing to do is to edit your viwes in your crud_api dir,you edit it by pasting the following code in it.
from rest_framework.response import Response
from rest_framework import status, generics
from note_api.models import NoteModel
from note_api.serializers import NoteSerializer
import math
from datetime import datetime
class Notes(generics.GenericAPIView):
serializer_class = NoteSerializer
queryset = NoteModel.objects.all()
def get(self, request):
page_num = int(request.GET.get("page", 1))
limit_num = int(request.GET.get("limit", 10))
start_num = (page_num - 1) * limit_num
end_num = limit_num * page_num
search_param = request.GET.get("search")
notes = NoteModel.objects.all()
total_notes = notes.count()
if search_param:
notes = notes.filter(title__icontains=search_param)
serializer = self.serializer_class(notes[start_num:end_num], many=True)
return Response({
"status": "success",
"total": total_notes,
"page": page_num,
"last_page": math.ceil(total_notes / limit_num),
"notes": serializer.data
})
def post(self, request):
serializer = self.serializer_class(data=request.data)
if serializer.is_valid():
serializer.save()
return Response({"status": "success", "note": serializer.data}, status=status.HTTP_201_CREATED)
else:
return Response({"status": "fail", "message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
class NoteDetail(generics.GenericAPIView):
queryset = NoteModel.objects.all()
serializer_class = NoteSerializer
def get_note(self, pk):
try:
return NoteModel.objects.get(pk=pk)
except:
return None
def get(self, request, pk):
note = self.get_note(pk=pk)
if note == None:
return Response({"status": "fail", "message": f"Note with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)
serializer = self.serializer_class(note)
return Response({"status": "success", "note": serializer.data})
def patch(self, request, pk):
note = self.get_note(pk)
if note == None:
return Response({"status": "fail", "message": f"Note with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)
serializer = self.serializer_class(
note, data=request.data, partial=True)
if serializer.is_valid():
serializer.validated_data['updatedAt'] = datetime.now()
serializer.save()
return Response({"status": "success", "note": serializer.data})
return Response({"status": "fail", "message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
note = self.get_note(pk)
if note == None:
return Response({"status": "fail", "message": f"Note with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)
note.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
This code allows you to import your views to the web api , so that it can be iwed on your website.
Inorder to make usres to interact with the API views defined in the crud-api, we are going to create urls that map them to the website.
We willl do this by adding the first code to our crud_api dir and the second to the credentials dir, bothin the url file
from django.urls import path
from note_api.views import Notes, NoteDetail
urlpatterns = [
path('', Notes.as_view()),
path('<str:pk>', NoteDetail.as_view())
]
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/notes/', include('note_api.urls'))
]
Teh first code enables us to define the crud api routes in crud_api/url.py dir while the second code enables us to ad a base url that references the urls defined in the crud_api/url.py dir to the credentials projects.
STEP 8
We have almost come to the end of this article, now all you nedd to ddo is to the migrate so that all the changes that have been made will be applied to ypour server.
You do this by using the command
python manage.py migrate
Once it is done you should see this
(api) C:\Users\USER\userApi\api\credentials> python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK python manage.py migrate
After this you can now create your superuser and then run your server. If it runs successftully you can now log into the Djanog admin.
Thanks for reading guys.
See you in my next post .