In our previous tutorial, we have provided guide to install and run your very first project with MoCherry – The CherryPy MongoDB REST webservice engine. Here we will explain to create a sample REST based webservice with the framework.

Problem Statement

We have to build an article management system where users can create / list / view / update / delete articles based using REST webservice.

For the above problem statement we will be using a new application inside our base project named “cms”, which will have it’s own models and views.

Step 1: Create URLs for router

MoCherry support exactly similar routing capabilities like CherryPy so when an application is created you will get a “urls.py” inside your root folder. There we will be creating URLs for REST based CRUD operations. So lets use following urls.py file.

import cherrypy

from app.views import IndexViewset
from cms.views import ArticleViewset, ArticleDetailsViewset  # import viewsets from application "cms"

def url_mapper():
    mapper = cherrypy.dispatch.RoutesDispatcher()
    mapper.connect('index', '/', controller=IndexViewset(), action='index')

    mapper.connect('article_create_list', '/articles/', controller=ArticleViewset(), action='index')
    mapper.connect('article_details_fetch_update_delete', '/articles/{article_id}/', controller=ArticleDetailsViewset(), action='index')

    return mapper

Step 2: Define Views with reference to the URLs

Once URL mapping is done we have to define our views which is referred from urls.py. View definition should be done inside views.py file as follows:

from mocherry.library.views import APIViewset
from mocherry.library.databases import DatabaseConnection
from mocherry.library.http import status
from mocherry.settings import CONFIG
from datetime import datetime
from .models import Article

class ArticleViewset(APIViewset):
    def POST(self, request, *args, **kwargs):
        payload = request.json

        mongo_uri = CONFIG['database']['default']['uri']
        with DatabaseConnection(mongo_uri):
            article_info = Article()
            article_info.title = payload['title']
            article_info.description = payload['description']
            article_info.tags = payload['tags']
            article_info.modified_on = datetime.now()
            article_info.save()
            
        return self.send_response({
            'id': str(article_info.pk)
        })
    
    def GET(self):
        article_list = []

        mongo_uri = CONFIG['database']['default']['uri']
        with DatabaseConnection(mongo_uri):
            available_articles = Article.objects()
            for article_info in available_articles:
                article_list.append({
                    'id': str(article_info.pk),
                    'title': article_info.title,
                    'description': article_info.description,
                    'tags': article_info.tags,
                    'created_on': datetime.timestamp(article_info.created_on),
                    'modified_on': datetime.timestamp(article_info.modified_on)
                })

        return self.send_response({
            'articles': article_list
        })


class ArticleDetailsViewset(APIViewset):
    def GET(self, article_id):
        article_info = {}

        mongo_uri = CONFIG['database']['default']['uri']
        with DatabaseConnection(mongo_uri):
            available_article = Article.objects(pk=article_id).first()
            if available_article is None:
                return self.send_response({
                    'error': {
                        'message': 'Invalid article id'
                    }
                }, status_code=status.HTTP_404_NOT_FOUND)
            else:
                article_info = {
                    'id': str(available_article.pk),
                    'title': available_article.title,
                    'description': available_article.description,
                    'tags': available_article.tags,
                    'created_on': datetime.timestamp(available_article.created_on),
                    'modified_on': datetime.timestamp(available_article.created_on)
                }
        
        return self.send_response(article_info)

    def PUT(self, request, article_id):
        payload = request.json
        mongo_uri = CONFIG['database']['default']['uri']
        with DatabaseConnection(mongo_uri):
            available_article = Article.objects(pk=article_id).first()
            if available_article is None:
                return self.send_response({
                    'error': {
                        'message': 'Invalid article id'
                    }
                }, status_code=status.HTTP_404_NOT_FOUND)
            else:
                available_article.title = payload['title']
                available_article.description = payload['description']
                available_article.tags = payload['tags']
                available_article.modified_on = datetime.now()
                available_article.save()

        return self.send_response({
            'id': article_id
        })

    def DELETE(self, article_id):
        mongo_uri = CONFIG['database']['default']['uri']
        with DatabaseConnection(mongo_uri):
            available_article = Article.objects(pk=article_id).first()
            if available_article is None:
                return self.send_response({
                    'error': {
                        'message': 'Invalid article id'
                    }
                }, status_code=status.HTTP_404_NOT_FOUND)
            else:
                available_article.delete()

        return self.send_response({})

For your convenience, we have published the entire code to github repository as follows: https://github.com/techunits/mocherry-sample-rest-app