Python Web API Development with JSONClasses

Victor Teo
5 min readOct 28, 2021

--

Developing Web API hasn’t been so much easy at the day JSONClasses is out. JSONClasses is a declarative data pipeline and object graph framework. It has an inborn integration and support with databases and HTTP frameworks. With JSONClasses, writing a full-fledged backend server becomes writing a single program file. Let’s dive right in.

Create a New Project

First let’s create a new directory and set it up with Python’s venv. To run JSONClasses, Python 3.10 is required. If you don’t have Python 3.10 installed, you can download it here.

Next, let’s install JSONClasses and some dependencies we’ll be using for this project. Create a new file named requirements.txt with the following content.

Run pip install -r requirements to install the dependencies. If you are using mypy to do the type checking, create a file named mypy.ini with the following content.

Currently JSONClasses only supports MongoDB as it’s underlying database. If you haven’t have it installed, see the instructions. After installing, you can type mongosh in the terminal to check it’s running status.

The First Class

Let’s create a new file named app.py, this is the only program file for this project. Everything will be written inside of it.

Let’s take a closer look of what we did in this file.

  1. We created a JSON class named Article.
  2. It has an id, which is the unique identifier of this object.
  3. It has two string fields named title and content.
  4. The field words is a calculated field.
  5. The field published has a default value which is False.
  6. created_at and updated_at are timestamps for recording the creation date and modification date of an object.
  7. The decorator @jsonclass turns a plain Python class into a JSON class.
  8. The decorator @pymongo adds a bunch of database utilities to the class.
  9. The decorator @api created the CRUD routes in a RESTful API style.
  10. Final and last, we created a Flask server to handle HTTP requests.

Now run it with flask run, a server will be served at localhost:5000. Open any HTTP client and do the following POST request, you will create a new article in the database.

You may create more articles and then do a list query.

The result may look like this.

You can filter and sort the results or limit the output fields.

Now grab an id of an article and paste it into the patch request. You can update an existing article.

By changing the request method from PATCH to GET, you can query an object by id.

If you request the same URL with DELETE method, you can safely delete an record from the database.

This way, we declare our article model with detailed yet concise requirements, and gain the most intuitive CRUD routes. There are still something worth to mention.

In the previous code example, if you want to make title automatically trimmed, you could append the following types modifier pipeline to title.

You can also limit the maximum content length for content.

The other way to limit its content length is by using truncate.

The difference between maxlength and truncate is that maxlength prevents frontend to send a value which length is larger than expected. While truncate truncates it if it’s longer than expected.

The words types modifier pipeline is the most complicated. By providing a getter, it’s not stored property anymore. It’s calculated. The this.fval('content') means grab the value at the fieldcontent. A getter can be provided by a callable, too. Depends on your preference, you can write it in pipeline style or callable style.

Normally a non optional type should have a required modifier at the end. In this case, you know that getter will not return a None value, the required modifier can be omitted.

Adding Relationship

JSONClasses is not only a data pipeline framework, but also an object graph framework. Object relationships are deeply built into its core. Setting up relationships are deadly simple. Now let’s add the user model and setup the owner relationship with articles.

The linkto modifier turns a field’s storage type to local key. The linkedby modifier turns a field’s storage type to foreign key. The linkedby’s argument is the field name of the corresponding field. In this way, the framework understands the requirements and setups the internal stuffs for us.

Restart the server with flask run, you can do CRUD requests to /users routes. The email field is unique. If you create a user with an existing email, you will get an error. This uses database’s unique index. It guarantees field value to be unique.

To create an article, an authorId should be included in the post body. Otherwise it won’t be created since the author field is required. Later, we will implement user session aka signing in. We can automatically pass the signing in user’s id to the field afterwards. But for now, let’s include it in the post body.

You can query articles by author id. You can also include author data in articles.

User Session

The majority of modern web apps require users to login. And without user session, the API server is not complete. The user plays an important role in the web products. Different roles of users do different things in the same product platform. In JSONClasses, the signed in user is called operator. It can be a normal user, a seller, a singer, or an administrator. Adding user session is quite simple, too.

Let’s see what we have changed.

  1. We imported @authorized and put this decorator on top of @api.
  2. We added authidentity to email field. JSONClasses will use this field as authentication identity.
  3. The password field is writeonly. It will not be outputted into the response json. It’s salted. We will not save clear text in the database. The authbycheckpw is a syntax sugar for authby(types.checkpw(types.passin)). If a user types a wrong password, a session token will not be generated for him/her.
  4. The asopd we added to article’s author field will automatically pull the id of the operator and assign it to the field.

To sign in, send a post request to /{resource_name}/session.

You will get back a token and the user’s data. Then, copy this token and paste it into authorization header. This header identifies the operator’s identity. With user signed in, now create an article, the signed in user is automatically set to article’s author.

Conclusion

JSONClasses has a lot of great features to make coding happier, make life easier and make money more. However, in this introduction post, we can only cover a little. Just like how React.js, Jetpack Compose and SwiftUI changes the way frontend apps are built, JSONClasses aims to change the backend development to a declarative manner. Tons of time are saved and the maintainability just goes up.

To learn it, you can read the guides and API documentation on its website.

I’d really glad to see you join us, be part of us. Join the JSONClasses community to build great things and live a better life with us.

--

--