- Introduction
- Overview
- Importance of Data Entities in Graphweaver
- Creating Data Entities
- Defining Data Entities for Different Data Providers
- Example: Creating a Database Entity for MySQL
- Example: Creating a Database Entity for PostgreSQL
- Example: Creating a REST Entity
- Example: Creating a Xero Entity
- Relationships
- Conclusion
Introduction
Data entities play a crucial role in Graphweaver, serving as the building blocks that define the structure and behavior of data within the system.
In this article, we will explore the concept of data entities, their significance in Graphweaver, and how to create and customize them.
Overview
Data entities are representations of various data sources within Graphweaver. They act as the bridge between the underlying data providers and the GraphQL schema.
A data entity defines the shape of the data, including its properties and relationships.
By defining data entities, you establish a clear mapping between the data sources and the GraphQL schema.
This allows you to seamlessly integrate and manipulate data from different sources in a unified manner.
Data entities may have more properties than you choose to expose via the GraphQL API and it is this layer of abstraction that gives you a great deal of flexibility.
Importance of Data Entities in Graphweaver
Data entities are a part of the architecture principles of Graphweaver. Although it may seem like creating two entities each time is redundant it does offer a number of advantages:
- Abstraction of Data Sources: Data entities abstract away the complexities of interacting with various data providers. They provide a unified interface to access and manipulate data, regardless of the underlying source.
- Consistent GraphQL Schema: Data entities are “linked” to a GraphQL entity by mapping to specific types and fields. This allows you to decide which properties are exposed in the GraphQL schema.
- Data Manipulation and Validation: Data entities allow you to define validation rules, data transformations, and custom business logic within the schema layer. This ensures data integrity and consistency before interacting with the underlying data sources. An example would be a database constraint.
Creating Data Entities
To create a data entity in Graphweaver, you start by extending the base entity class specific to the data provider.
For example, when creating a database entity for MySQL, you would extend the BaseEntity
class inside the @exogee/graphweaver-mikroorm
package.
Here's an example of creating a User
entity for a MySQL database:
import { BigIntType, Entity, PrimaryKey, Property } from '@mikro-orm/core';
import { BaseEntity } from '@exogee/graphweaver-mikroorm';
@Entity()
export class User extends BaseEntity {
@PrimaryKey({ type: BigIntType })
id!: string;
@Property({ type: String })
firstName!: string;
@Property({ type: String })
lastName!: string;
}
Note that the above example is specific to a database entity.
Each data provider has its own set of decorators or configuration options for defining entity properties, relationships, and other provider-specific details.
Defining Data Entities for Different Data Providers
In this section, we'll explore how to define data entities for different data providers supported by Graphweaver. We'll provide examples for creating entities in MySQL, PostgreSQL, REST APIs, and Xero.
Example: Creating a Database Entity for MySQL
Below is a simple example of a user entity that is backed by a MySQL data source.
import { BigIntType, Entity, PrimaryKey, Property } from '@mikro-orm/core';
import { BaseEntity } from '@exogee/graphweaver-mikroorm';
@Entity()
export class User extends BaseEntity {
@PrimaryKey({ type: BigIntType })
id!: string;
@Property({ type: String })
firstName!: string;
@Property({ type: String })
lastName!: string;
}
Example: Creating a Database Entity for PostgreSQL
Similar to the previous example, the below example is a data entity for PostgreSQL:
import { BigIntType, Entity, PrimaryKey, Property } from '@mikro-orm/core';
import { BaseEntity } from '@exogee/graphweaver-mikroorm';
@Entity()
export class User extends BaseEntity {
@PrimaryKey({ type: BigIntType })
id!: string;
@Property({ type: String })
username!: string;
@Property({ type: String })
email!: string;
}
As you can see the MySQL and PostgreSQL are identical!
Example: Creating a REST Entity
This example uses the Rest data provider:
import { BaseEntity, Field } from '@exogee/graphweaver-rest';
export class User extends BaseEntity {
@Field()
name!: string;
@Field()
url!: string;
}
Example: Creating a Xero Entity
The Xero data provider is slightly different because it already knows the entity types available. So for this data provider you can simply import the xero-node
entity, like this:
import { Account, AccountType } from 'xero-node';
Relationships
While data entities provide a solid foundation for working with data in Graphweaver, you may need to customize them to meet your specific requirements.
One common customization is adding relationships between entities to establish connections and enable efficient data querying.
To add relationships between data entities, you can leverage decorators or methods provided by Graphweaver Data Provider. These mechanisms allow you to define associations such as one-to-one, one-to-many, or many-to-many relationships.
By establishing relationships, you can retrieve related data in a structured and optimized manner.
Here's an example of adding a many-to-many relationship to the Task
entity:
import { BigIntType, Entity, PrimaryKey, Property, ManyToMany, Collection } from '@mikro-orm/core';
import { BaseEntity, ExternalIdField } from '@exogee/graphweaver-mikroorm';
import { Tag } from './tag';
@Entity()
export class Task extends BaseEntity {
@PrimaryKey({ type: BigIntType })
id!: string;
@Property({ type: String })
description!: string;
@ExternalIdField({ from: 'user' })
@Property({ type: BigIntType })
userId!: string;
@ManyToMany(() => Tag, (tag) => tag.tasks, { owner: true })
tags: Collection<Tag> = new Collection<Tag>(this);
}
In the above example, we define a many-to-many relationship between the Task
entity and the Tag
entity. The @ManyToMany
decorator specifies the target entity and the mapping information.
This allows you to access all the tags associated with a task through the tags
property.
These two data entities are held in the same data source. So we can link them this way. However, sometimes you may only hold an ID to an external system. In the example above you can see this is the case with the userId field:
@ExternalIdField({ from: 'user' })
@Property({ type: BigIntType })
userId!: string;
By adding the ExternalIdField
decorator to this property you are informing Graphweaver that this property is an ID to a data entity in another data source.
Conclusion
Data entities serve as the building blocks of the Graphweaver system, providing a clear mapping between data sources and the GraphQL schema.
They play a crucial role in abstracting data sources, maintaining a consistent schema, and enabling data manipulation and validation.
By understanding the importance of data entities and learning how to create and customize them, you can leverage the full potential of Graphweaver and build sophisticated GraphQL APIs that integrate seamlessly with various data providers.