Payload and the experience of interacting with it

Hi! My name is Sergey, I am a lead developer at Lad. This article will discuss my experience with Payload.

In our company, we used Payload to create quick prototypes and MVP projects. We chose Payload as a very flexible and interesting tool that provides a lot of functionality out of the box, an admin panel, and basic work with users.

The article will mainly concern interactions from the backend side.

Pros and Benefits of Payload

  1. Simplifies project development, which means quick and easy initial setup and a ready-made project structure (which can be a downside in general).

  1. Multilingual support out of the box.

  1. Provides authorization out of the box.

  1. Authentication occurs using the classic “email — password” combination.

A Bearer token is used for authorization.

All the necessary set of user-friendly controls at once:

This can also be extended via PassportJs, but in practice we didn't have a need to use it.

  1. Access control for CRUD operations.

  2. Convenient for rapid prototyping. If you want to launch a project in 30 minutes, describe several entities – the solution is extremely convenient.

  3. Provides basic CRUD.

After describing an entity, a set of routes is created for it, ready for work:

  1. Query queries (GraphQL).

    On the frontend side, it becomes possible to perform simple queries, including sorting and filtering (equals, less_then, in, etc.).

  2. Standardization of queries. Errors, pagination, answers, etc. – everything is in a single style.

  3. Support for Mongodb and Postgres and simple, fast basic work with them (in our case we used only mongo).

  4. Quick description of a collection and generation of interfaces based on it:

export const Clients: CollectionConfig = {
 slug: 'clients',
 auth: {
   depth: 1,
   tokenExpiration: 28800,
   maxLoginAttempts: 5,
   lockTime: 30 * 1000,
 },
 labels: {
   plural: 'Клиенты',
   singular: 'Клиент',
 },
 admin: {
   useAsTitle: 'name',
 },
 fields: [
   {
     name: 'name',
     type: 'text',
     label: 'Имя',
   },
   {
     name: 'favoriteNumber',
     type: 'number',
     label: 'Любимое число',
   },
   {
     type: 'date',
     label: 'Дата рождения',
     name: 'dateOfBirth',
   },
 ],
};

Output interface:

/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "clients".
*/
export interface Client {
 id: string;
 name?: string | null;
 favoriteNumber?: number | null;
 dateOfBirth?: string | null;
}
  1. Good and convenient admin panel out of the box:

  1. The system provides many hooks on entities and fields. This can often be very convenient.

hooks: {
afterRead: [afterReadUser], 
afterDelete: [afterDeleteUser],
}

What are the disadvantages of Payload that we encountered?

Some advantages have disadvantages.

  1. The problem of hooks. The system provides several levels of hooks. Some hooks are at the field level, others are at the collection level. It is up to us to describe hooks for creation, modification, and deletion.

    Sounds pretty good. But at a certain stage of working with a project it turns out that not all things are convenient and possible to do through hooks + there are too many of them.

    This is starting to look like a complication. The problem arises with the fact that you have to remember and keep track of all the described hooks. It looks like a problem with callbacks – this is some kind of unpredictability of the code: at what point and what will be executed? Everything is too nonlinear. Too confusing.

  2. Types and fields. They look more like they are tailored for the admin panel, not the backend part. A good example is the boolean type, which is called checkbox here:

  1. Problem with mongoose. At the time of development, Payload used an old mongoDb driver. It is not possible to update it just like that. Various problems arise, especially problems related to types.

  2. Databases. Too high level of abstraction. DB – mongoose – wrapper on Payload. There is some unpredictability of what can happen.

  3. The Payload concept forces you to write a database in a style closer to relational with a huge number of tables and relationships between them.

  4. If more complex queries are needed, they will work bypassing hooks. You have to monitor this very carefully. Often this greatly complicates and slows down the development process.

  5. Minor problems that arise during the work process:

    • Unable to type JSON type;

    • cannot specify minimum array value 0;

    • and many other moments that are not critical, but are very annoying during the work process.

  1. If you need to do more complex validation and data checking, you have to make a custom controller or wrap it with additional hooks. But then it seems like the concept of something “fast out of the box” breaks.

  2. You have to use custom things for validation or check the fields in the handler itself.

  3. Due to the specific architecture, it is impossible to talk about microservices.

  4. In versions before 2.0 graphQl was old and deprecated and there was nothing you could do about it.

  5. It is not possible to rewrite the error handler.

  6. The forum (community help) is generally focused on frontend issues and is quite useless for the backend.

conclusions

When working with Payload, it should be taken into account that some problems may arise when we want functionality that is slightly larger than what is provided out of the box. Version limitations, custom code may conflict with what is in the system, or other situations described in the article may arise. But all these disadvantages are inherent not only to Payload, but to any “boxed solutions”.

To summarize the entire experience of interaction with Payload, it should be noted that it is indeed a very convenient tool for creating prototypes and MVPs. In our case, it allowed us to create two large, high-quality MVPs with a large amount of functionality in a short time.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *