Microservice app with DRF — Part1

Introduction

Decoupling the development of an application into the Frontend and the Backend is a common architectural implementation in modern app development. With the Frontend and Backend decoupled, there needs to be a communication middleware that will allow data exchange between these components. This is where application programming interfaces (APIs) come in.

This guide explores API development in REST using Django, which already has a package for REST API development called Django Rest Framework (DRF). The guide assumes you have a basic understanding of APIs and Django web framework and at least intermediate-level proficiency in Python.

About DRF

The Django Rest Framework is a third-party package that empowers a Django app with REST API capabilities.

To install the package, run the command:

pip install django-rest-framework

Create a Sample App

This will be a Django app that displays data from the default Sqlite3 database. The data is a list of countries and their currency names.

Fire up a new Django project by running this command.

> django-admin startproject countries

Next, create an app and name it currency_country using this command.

> python3 manage.py startapp currency_country

The app is now set up. What remains is to develop the country model, the DRF API resources, and provide URLs to the API resources. The code block below shows the model and what fields make up the database table. Copy the code block into the models.py file.

from django.db import modelsclass Country(models.Model):
country_name = models.CharField(max_length=20)
local_currency = models.CharField(max_length=20)
added_on = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.country_name

The model needs data. To add the data, access the admin panel that requires superuser access. The next step is to create a superuser account using the following command.

python manage.py createsuperuser

This will be an interactive process where you will give essential details and register your user.

For the app and model to be visible, they need to be registered with the Django project and admin.py. To register the app and rest framework, a third-party app, add their names to the list of installed apps in settings.py.

Copy the list below to your settings.py and replace the existing list.

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'currency_country',
"rest_framework",
]

To ensure the Country model is visible on the admin panel, register it in the admin.py file.

Add the code block below to your admin.py file.

from django.contrib import admin
from .models import Country
admin.site.register(Country)

DRF Serializers

DRF serializers convert Django data types, such as querysets, into a format that can be rendered into JSON or XML. For this app, you only need to create the Country serializer. In the currency_country app, create a file named serializers.py and add the code block below.

from rest_framework import serializers
from .models import Country
class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = Country # this is the model that is being serialized
fields = ('country_name', 'local_currency')

API Requests

To service a GET or POST request, you need a view that will return all countries in a serialized fashion. To achieve this, create a view within the views.py file and add the view that will return all countries, serialized.

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Country
from .serializers import CountrySerializer
@api_view(['GET', 'POST'])
def country(request):

if request.method == 'GET': # user requesting data
snippets = Country.objects.all()
serializer = CountrySerializer(snippets, many=True)
return Response(serializer.data)
elif request.method == 'POST': # user posting data
serializer = CountrySerializer(data=request.data)
if serializer.is_valid():
serializer.save() # save to db
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

URL Configuration

To configure the URL, configure the main project’s urls.py file to direct any traffic to the currency_country app using the path function, as in the codeblock below.

from django.urls import path, include
from django.contrib import admin
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('currency_country.urls')),
]

Next, create a urls.py file and, using the path, direct the traffic to your view function.

from django.urls import path
from .views import country
urlpatterns = [
path('country/', country, name="countries")
]
API result page

Types of APIs

We have two types of application deployment.

  • Monolothic:

Monolithic architecture is built as one large system and is usually one code-base. Monolithic application is tightly coupled and entangled as the application evolves, making it difficult to isolate services for purposes such as independent scaling or code maintainability.

It extremely difficult to change technology or language or framework because everything is tightly coupled and depend on each other.

When developing a server-side application you can start it with a modular hexagonal or layered architecture which consists of different types of components:

  • Presentation -> responsible for handling HTTP requests and responding with either HTML or JSON/XML (for web services APIs).
  • Business logic -> the application’s business logic.
  • Database access -> data access objects responsible for access the database.
  • Application integration ->integration with other services (e.g. via messaging or REST API).

Despite having a logically modular architecture, the application is packaged and deployed as a monolith. Benefits of Monolithic Architecture

  • Simple to develop.
  • Simple to test. For example you can implement end-to-end testing by simply launching the application and testing the UI with Selenium.
  • Simple to deploy. You just have to copy the packaged application to a server.
  • Simple to scale horizontally by running multiple copies behind a load balancer.

In the early stages of the project it works well and basically most of the big and successful applications which exist today were started as a monolith.

Drawbacks of Monolithic Architecture

  • This simple approach has a limitation in size and complexity.
  • Application is too large and complex to fully understand and made changes fast and correctly.
  • The size of the application can slow down the start-up time.
  • You must redeploy the entire application on each update.
  • Impact of a change is usually not very well understood which leads to do extensive manual testing.
  • Continuous deployment is difficult.
  • Monolithic applications can also be difficult to scale when different modules have conflicting resource requirements.
  • Another problem with monolithic applications is reliability. Bug in any module (e.g. memory leak) can potentially bring down the entire process. Moreover, since all instances of the application are identical, that bug will impact the availability of the entire application.
  • Monolithic applications has a barrier to adopting new technologies. Since changes in frameworks or languages will affect an entire application it is extremely expensive in both time and cost.
  • Microservice:

Microservices architecture is built as small independent module based on business functionality. In microservices application, each project and services are independent from each other at the code level. Therefore it is easy to configure and deploy completely and also easy to scale based on demand.

Microservices Architecture:

Microservice based of an example

The idea is to split your application into a set of smaller, interconnected services instead of building a single monolithic application. Each microservice is a small application that has its own hexagonal architecture consisting of business logic along with various adapters. Some microservices would expose a REST, RPC or message-based API and most services consume APIs provided by other services. Other microservices might implement a web UI.

The Microservice architecture pattern significantly impacts the relationship between the application and the database. Instead of sharing a single database schema with other services, each service has its own database schema. On the one hand, this approach is at odds with the idea of an enterprise-wide data model. Also, it often results in duplication of some data. However, having a database schema per service is essential if you want to benefit from microservices, because it ensures loose coupling. Each of the services has its own database. Moreover, a service can use a type of database that is best suited to its needs, the so-called polyglot persistence architecture.

Some APIs are also exposed to the mobile, desktop, web apps. The apps don’t, however, have direct access to the back-end services. Instead, communication is mediated by an intermediary known as an API Gateway. The API Gateway is responsible for tasks such as load balancing, caching, access control, API metering, and monitoring.

The Microservice architecture pattern corresponds to the Y-axis scaling of the Scale Cube model of scalability.

Benefits of Microservices Architecture

  • It tackles the problem of complexity by decomposing application into a set of manageable services which are much faster to develop, and much easier to understand and maintain.
  • It enables each service to be developed independently by a team that is focused on that service.
  • It reduces barrier of adopting new technologies since the developers are free to choose whatever technologies make sense for their service and not bounded to the choices made at the start of the project.
  • Microservice architecture enables each microservice to be deployed independently. As a result, it makes continuous deployment possible for complex applications.
  • Microservice architecture enables each service to be scaled independently.

Drawbacks of Microservices Architecture

  • Microservices architecture adding a complexity to the project just by the fact that a microservices application is a distributed system. You need to choose and implement an inter-process communication mechanism based on either messaging or RPC and write code to handle partial failure and take into account other fallacies of distributed computing.
  • Microservices has the partitioned database architecture. Business transactions that update multiple business entities in a microservices-based application need to update multiple databases owned by different services. Using distributed transactions is usually not an option and you end up having to use an eventual consistency based approach, which is more challenging for developers.
  • Testing a microservices application is also much more complex then in case of monolithic web application. For a similar test for a service you would need to launch that service and any services that it depends upon (or at least configure stubs for those services).
  • It is more difficult to implement changes that span multiple services. In a monolithic application you could simply change the corresponding modules, integrate the changes, and deploy them in one go. In a Microservice architecture you need to carefully plan and coordinate the rollout of changes to each of the services.
  • Deploying a microservices-based application is also more complex. A monolithic application is simply deployed on a set of identical servers behind a load balancer. In contrast, a microservice application typically consists of a large number of services. Each service will have multiple runtime instances. And each instance need to be configured, deployed, scaled, and monitored. In addition, you will also need to implement a service discovery mechanism. Manual approaches to operations cannot scale to this level of complexity and successful deployment a microservices application requires a high level of automation.

Summary

Building complex applications is inherently difficult. A Monolithic architecture better suits simple, lightweight applications. There are opinions which suggest to start from the monolith first and others which recommend not to start with monolith when your goal is a microservices architecture. But anyway it is important to understand Monolithic architecture since it is the basis for microservices architecture where each service by itself is implemented according to monolithic architecture. The Microservices architecture pattern is the better choice for complex, evolving applications. Actually the microservices approach is all about handling a complex system, but in order to do so the approach introduces its own set of complexities and implementation challenges.

Part 2:

https://hasansajedi.medium.com/microservice-app-with-drf-part2-1c94cb0c5c05

Refrences:

  1. Introduction to Microservices
  2. Monolith First

--

--

--

Python developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Stop Learning Golang Like This

VSCode for Apple Silicon based Macs (ARM)

Contribution in OpenSource projects

Lumps of source code

Docker Tip: How to configure and rotate logs

Make A Motion Detector with Micro:bit and Elecfreaks Octopus Kits

Python tricks I wish I knew earlier

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Hasan Sajedi

Hasan Sajedi

Python developer

More from Medium

When to Use Blank and Null on Django Models

Test-Driven-Development with Django: Unit Testing & Integration testing with Docker, Flask & Github…

Django Github CI/CD

Playing around with Django JWT

Dockerizing Django Application — Gunicorn and Nginx