entity-routes logo
Docs

Formating#

The writer process each response item/items and call every Decorator functions that are registered.

These are the defaults decorator functions that will be used when enabled in WriterOptions :

FunctionDescriptionWriterOptions's keyDefault enabled
setComputedPropsOnItemAdd computed properties to this itemshouldSetComputedPropsOnItemtrue
setSubresourcesIriOnItemSet subresources IRIshouldSetSubresourcesIriOnItemtrue
flattenItemFlatten item with only id if neededshouldEntityWithOnlyIdBeFlattenedtrue

The Writer also performs the following tasks :

Examples#

Below examples use these entities

#
ts
1abstract class AbstractEntity {
2 @PrimaryGeneratedColumn()
3 id: number;
5 @Groups(["details"])
6 get repository() {
7 return getRepository(this.constructor.name);
8 }
10 @Groups(["details"])
11 getTableName() {
12 return this.repository.metadata.tableName;
13 }
16@Entity()
17class Role extends AbstractEntity {
18 @Column()
19 identifier: string;
22@Entity()
23class User extends AbstractEntity {
24 @Column()
25 name: string;
27 @ManyToOne(() => Role)
28 role: Role;

1. Remove any object that is not another Entity#

Let's say you have a User entity such as :

#
ts
1@EntityRoute({ path: "/users", operation: ["details"] })
2@Entity()
3class User extends AbstractEntity {
4 @Column()
5 name: string;
7 @ManyToOne(() => Role)
8 role: Role;
10 @Groups(["details"])
11 get repository() {
12 return getRepository(this.constructor.name);
13 }
15 @Groups(["details"])
16 getTableName() {
17 return this.repository.metadata.tableName;
18 }
  • The repository key will not be returned in response since it does not implement the GenericEntity interface.
  • The tableName will be returned since it's just a string
#
json
1{
2 "@context": {
3 "operation": "details",
4 "entity": "user"
5 },
6 "id": 1,
7 "name": "Alex",
8 "tableName": "user"
9}
GET:/users/1

2. Flatten item with only id if needed#

Let's say you have a Role and a User entity such as :

#
ts
1abstract class AbstractEntity {
2 @Groups("all")
3 @PrimaryGeneratedColumn()
4 id: number;
5}
7@Entity()
8class Role extends AbstractEntity {
9 @Column()
10 identifier: string;
13@EntityRoute(
14 { path: "/users", operation: ["details"] },
15 { defaultWriterOptions: { shouldEntityWithOnlyIdBeFlattened: true } }
17@Entity()
18class User extends AbstractEntity {
19 @Groups(["details"])
20 @Column()
21 name: string;
23 @Groups(["details"])
24 @ManyToOne(() => Role)
25 role: Role;

Since no properties except id is exposed on the user.details route scope :

  • The role relation will be returned as an IRI.
  • If you opted-out of IRIs, then the id will be returned as is.
#
json
1{
2 "@context": {
3 "operation": "details",
4 "entity": "user"
5 },
6 "id": 1,
7 "name": "Alex",
8 "role": "/api/role/321"
9 // or if not using IRIs "role": 321
GET:/users/1

3. Set subresources IRI#

#
typescript
1@EntityRoute()
2@Entity()
3class Article extends AbstractEntity {
4 @ManyToOne(() => User, (user) => user.articles)
5 author: User;
7 @Column()
8 title: string;
9}
11@EntityRoute(
12 { path: "/users/", operations: ["list"] },
13 { defaultWriterOptions: { shouldSetSubresourcesIriOnItem: true } }
15@Entity()
16class User extends AbstractEntity {
17 @Groups({ user: ["create", "details"], article: ["list"] })
18 @Column()
19 name: string;
21 @Subresource(() => Article)
22 @OneToMany(() => Article, (article) => article.author)
23 articles: Article[];
  • The articles property will be set to its IRI /api/user/1/articles (if not exposed through @Groups)
#
json
1{
2 "@context": {
3 "operation": "details",
4 "entity": "user"
5 },
6 "articles": "/api/users/1/articles",
7 "id": 1,
8 "name": "Alex"
9}
GET:/users/1

4. Sort item's property keys#

#
typescript
1@EntityRoute({ path: "/users/", operations: ["list"] }, { defaultWriterOptions: { shouldSortItemKeys: true } })
2@Entity()
3class User extends AbstractEntity {
4 @Groups(["details"])
5 @Column()
6 name: string;
8 @Groups(["details"])
9 @OneToMany(() => Article, (article) => article.author)
10 articles: Article[];
  • All responses keys will be sorted alphabetically, recursively through all nested entities as well
Prev
Introduction
Next
Examples