Skip to content
This repository has been archived by the owner on Jun 22, 2021. It is now read-only.

Latest commit

 

History

History
119 lines (97 loc) · 8.39 KB

options.md

File metadata and controls

119 lines (97 loc) · 8.39 KB

Options

The facade functions have some common options that they use.

Id

This is a string that uniquely identifies an entity. In some databases the identifier for an entity may actually be stored as a different data type (e.g. a number or MongoId), but the Facade functions will always convert this to a string for compatibility across database implementations.

It's important to know that these identifiers are user-defined, meaning that they will not be generated by the database. The reason for this is that allowing the user to define the identifier enables optimistic updates to be handled more easily, especially on the client-side. Frameworks and libraries like Meteor and Mongoose also work in this way.

Having said all of that, there may be ways to allow the database to generate the identifiers in concrete implementations of the Facade, but only when you can specify constructDocument and constructEntity properties in the factory of those implementations. The Knex implementation of the Facade is an example of a concrete implementation that allows you to specify these properties in its factory.

Entity

This is an object that contains all of the entity's properties. The word "entity" has been borrowed from Entity-Relationship Models/Diagrams and has been used instead of the word "model" to avoid confusion with MVC.

This interface is user-defined hence not contained in this package, the interface below demonstrates what this might look like for a todo entity and extends the TypeScript Entity interface defined in this package. Note that the Entity interface already contains the id property.

When using js-entity-repos all entities should have a single unique identifier (the id property) because the Facade functions do not support composite keys. There are a number of pros and cons to this that you can discover with a little Googling, but be aware that some databases actually enforce a single identifier anyway (such as Mongo). The main reason composite keys are not supported here is that it simplifies routing in HTTP implementations of the Facade such as Axios and Express.

It's usually useful and recommended to create your own Entity interface to use as a base interface for your entities. This is useful for adding common properties across your entities such as timestamps (like createdAt and updatedAt). Since the js-entity-repos make no attempt at validation, you might also find it useful to use a validation package like Rulr.

import Entity from '@js-entity-repos/core/dist/types/Entity';

interface TodoEntity extends Entity {
  readonly description: string;
  readonly completed: boolean;
}

Patch

This is an object containing some of the entity's properties. This package uses TypeScript's Partial type applied to an Entity (using Partial<Entity>).

Filter

This is an object that filters the entities. The filter type definition currently supports the following operators which have been borrowed from Mongo. In some cases (like dates) you may need to use the convertPropertyFilter utility function.

Operator Description
$and Includes entities where all of the specified filters are true.
$or Includes entities where some of the specified filters are true.
$nor Includes entities where some of the specified filters are false.
$not Includes entities where a specified filter is not true.
$eq Includes entities where the value of a given property is equal to the specified value.
$ne Includes entities where the value of a given property is not equal to the specified value.
$lt Includes entities where the value of a given property is less than the specified value.
$lte Includes entities where the value of a given property is less than or equal to the specified value.
$gt Includes entities where the value of a given property is greater than the specified value.
$gte Includes entities where the value of a given property is greater than or equal to the specified value.
$in Includes entities where the value of a given property is equal to one of the specified values.
$nin Includes entities where the value of a given property is not equal to any of the specified values.
$search Includes entities where the value of a given property contains the specified value as a substring.

The filter below is comprehensive example using all of the operators.

{
  "$or": [
    {
      "numberProp1": {
        "$not": {
          "$gt": 0,
          "$lt": 1
        }
      }
    },
    {
      "$and": [
        {
          "stringProp1": "string value 1",
          "stringProp2": {
            "$search": "string value 2"
          },
          "numberProp2": {
            "$gte": 0,
            "$lte": 1
          },
          "numberProp3": { "$ne": 0 },
          "numberProp4": { "$eq": 0 }
        },
        {
          "stringProp3": {
            "$in": ["string value 3", "string value 4"]
          },
          "stringProp4": {
            "$nin": ["string value 5", "string value 6"]
          }
        }
      ]
    },
    ,
    {
      "$nor": [
        {
          "stringProp5": "string value 7"
        }
      ]
    }
  ]
}

Sort

This is an object where a key represents the entity property to be sorted and the value represents the direction to sort. The value should be 'asc' to sort in ascending order and 'desc' to sort in descending order. The properties are sorted in order of their definition in the sort option, for example, the following sort option { createdAt: 'desc', id: 'asc' } will sort by the createdAt property first and then the the id property.

This package contains the TypeScript Sort type definition. It also contains constants for 'asc' and 'desc' that should always be used to avoid breaking changes in the future.

Pagination

This is an object with three properties, limit, direction, and cursor. The limit property defines how many entities to return (maximum). The direction property defines whether the entities should be iterated through forwards (when 'forward') or backwards (when 'backward') from the cursor. The cursor property defines where to start iterating through the entities. Cursors have been used instead of skip and limit to avoid the pagination issues discussed by Rakhitha Nimesh.

Concrete implementations of the facade can use the createCursorFromEntity and createPaginationFilter utility functions to generate cursors.

This package contains the TypeScript Pagination interface and the TypeScript Cursor type definition. It also contains constants for 'forward' and 'backward' that should always be used to avoid breaking changes in the future.