how-to-develop-perfect-crud

Translations: EN(you are here), RU

🤔 What is this?

This article is an attempt to combine good practices that are useful to keep in mind and apply when developing a backend application.

It can be used as a checklist if:

🤔 Does this article only cover backend apps?

Because the author’s expertise lies mostly on the backend side, most suggestions will be useful for developing backend apps. However, a lot of the points covered in this article can also be handy for other types of development.

🤔 There is a lot in here, do I really need all of this?

The more features and practices you adopt in your project, the better. Applying all of them at once would be hard so consider your time 🕒 and effort 💪 to prioritize specific practices.

🤔 “This article is missing information about technology X”

If you have a proposal about covering a specific technology here, don’t be shy:

📖 Table of Contents

Code Style

Before development:

Try to adhere to the [testing pyramid] (https://martinfowler.com/articles/practical-test-pyramid.html) principle. Note that different test types require different tools. For end-to-end (e2e) testing you can try using Selenium or Cypress. Integration tests can be added via testcontainers.

⚙️Configuration & Infrastructure around Code

When writing the configuration for your application, use the 12factor principles. The diagram below is copied from the 12 Factor App Revisited article

API Design

If you think that REST+JSON option is not a great fit for your application design, or your task requires using a different format, it could be beneficial to familiarize yourself with some alternatives:

Authorization & Authentication

Authentication - is a process of verifying a user identity. The most common way to authenticate a user is to compare the password they entered with the password saved in the database.

The following strategies can be used to authenticate API users:

Authorization - granting a particular user the rights for performing specific actions. For instance: a user who was banned by admin cannot post comments (even though they have been successfully authenticated).

Some examples of libraries:

Additional links:

MVC Explanation

Goal: split the responsibilities between components. MVC is a type of architecture that allows a developer to build applications without excessive cognitive load (compared to other web architecture types)

Controller

📐✏️👷‍♀️Architecture, Design Patterns, Refactoring, etc

After grasping the concept of MVC, try developing a deeper understanding and study:

A few courses that I recommend:

🔒CRUD: Validations

Before persisting data in the database, one should:

P.S. Try following the principle of strong migrations to avoid blocking the DB.

CRUD: Operations

LIST (HTTP GET)

An API should not return all the fields for a model. Example of a response for a list of articles:

Sending a full text body is really unnecessary.

READ (HTTP GET)

Bonus points:

DESTROY (HTTP DELETE)

Additionally, you might considering implementing “soft-deletion” (hide deleted resources from users, but keep them in the DB)

External API Calls, Long-running tasks (And why we need message queue)

If an API needs to:

To do these operations, we will need a Queue, to which we’ll add or remove Tasks.

Examples of high-level libraries that solve the problem of scheduling, reading and processing tasks:

It is important to note that Redis is not the only option and it might not be suitable for all types of applications. Hence, it would be a good idea to learn at least two other advanced libraries for storing and processing queues - RabbitMG an d ‘Kafka’

Additional links:

📈Logs and Metrics

Metrics:

Set up Prometheus metrick with data about the state of HTTP API and application runtime. We recommend using settings that collect application performance metrics using RED (Rate Error Duration)](https://www.infoworld.com/article/3638693/the-red-method-a-new-strategy-for-monitoring-microservices.html) and USE (Utilization Saturation Errors) methodologies:

Logs:

🛡️Security

When dealing with modern single page applications written in popular frameworks like React, Vue.js or Angular, you are likely to encounter a scenario where a client domain will be different from your API domain. In this case, your API will have to include CORS headers to let the browser know that responses coming from the API are permitted.

Typically, a CORS module is already available in your framework of choice and you can use its defaults. If you need more a more granular configuration, here is a few libraries that can help:

You can learn more about CORS headers here here.

🚄Cache

First, try to ask yourself

If you are set on implementing caching, then you’ll need to:

WIP: Transactions, Locks, Isolation Levels, ACID

WIP: Full Text Search