Skyframe Documentation

Server: CRUD Endpoints Reference

Server: CRUD Endpoints Reference

Composition

One-to-One

class Child {
@OwnedBy(() => Parent)
parent: Parent;
}
class Parent {
@Owns(() => Child)
child: Child;
}
  • Parent

    • Create:

      • POST /api/parent

        Create parent with child:

        { name: 'parent name', child: { name: 'child' } }

        Create parent without child:

        { name: 'parent name' }
    • Read:

      • GET /api/parent/:id

        Server response:

        {
        id: 1,
        name: 'parent name',
        child: {
        id: 1,
        name: 'child name'
        }
        }
    • Update:

      • PATCH /api/parent/:id

        Update child fields:

        { child: { name: 'new child name' } }

        Update parent without affecting child:

        { name: 'new parent name' }
      • PUT /api/parent

        Remove nullable child:

        { name: 'parent name' } // child is not included anymore

        Remove child fields:

        { name: 'parent name', child: {} } // tries to set child.name to null, child.id will not be affected
    • Delete:

      • DELETE /api/parent/:id - Delete the parent and the child
  • Child

    • Create:

      • POST /api/parent/:parent_id/child

        Create child associated to a parent

        POST /api/parent/1/child
        Body: { name: 'child name' } // creates a new child and associates it to the parent with id 1
    • Read:

      • GET /api/parent/:parent_id/child/:id

        Server response:

        { id: 1, name: 'child name' }
    • Update:

      (Non of these endpoints affect the parent fields)

      • PATCH /api/parent/:parent_id/child/:id - Update only child fields included in the request body
      • PUT /api/parent/:parent_id/child/:id - Update all the child fields and try to remove the fields that are not included in the request body
    • Delete:

      • DELETE /api/parent/:parent_id/child/:id - Delete the child and try to set parent.child to null

One-to-Many

class Parent {
@Owns(() => Child)
children: Child[];
}
class Child {
@OwnedBy(() => Parent)
parent: Parent;
}
  • Parent

    • Create:

      • POST /api/parent

        Create parent without children:

        { name: 'parent name', children: [] }

        Create parent with children:

        {
        name: 'parent name',
        children: [
        { name: 'child 1' },
        { name: 'child 2' },
        { name: 'child 3' },
        ...
        ]
        }
    • Read:

      • GET /api/parent/:id

        Server response:

        {
        id: 1,
        name: 'parent name',
        children: [
        { name: 'child 1' },
        { name: 'child 2' },
        { name: 'child 3' },
        ...
        ]
        }
    • Update:

      • PATCH /api/parent/:id

        Bulk update children:

        // Updates child 1 and child 3
        {
        children: [
        { id: 1, name: 'new child 1' },
        { id: 3, name: 'new child 3' }
        ]
        }
      • PUT /api/parent/:id

        Remove all children:

        {
        name: 'parent name',
        children: []
        }

        Create and modify children:

        // Updates child 1 and creates a new child, also removes the rest of children that are not included
        {
        name: 'parent name',
        children: [
        { id: 1, name: 'updated child 1' },
        { name: 'new child' }
        ]
        }
    • Delete:

      • DELETE /api/parent/:id - Remove the parent and all its children
  • Child

    • Create:

      • POST /api/parent/:parent_id/child

        Add to a parent:

        { name: 'new child' }
    • Read:

      • GET /api/parent/:parent_id/child/:id

        Server response:

        { id: 1, name: 'child 1' }
    • Update:

      (Non of these endpoints affect the parent fields)

      • PATCH /api/parent/:parent_id/child/:id - Update only child fields included in the request body
      • PUT /api/parent/:parent_id/child/:id - Update all the child fields and try to remove the fields that are not included in the request body
    • Delete:

      • DELETE /api/parent/:parent_id/child/:id - Delete the child and remove it from parent.children array

Aggregation

One-to-Many or One-to-One

// Many children
class Parent {
@NeededBy(() => Child)
children: Child[];
}
class Child {
@ForeignKey(() => Parent)
parentId: number;
@Needs(() => Parent)
parent: Parent;
}
// Unique children
class Parent {
@NeededBy(() => Child)
child: Child;
}
class Child {
@Unique()
@ForeignKey(() => Parent)
parentId: number;
@Needs(() => Parent)
parent: Parent;
}
  • Parent

    • Create:

      • POST /api/parent/:id

        Create a parent that exists independently from the child:

        { name: 'parent 1' }
    • Read:

      • GET /api/parent

        Server response:

        {
        rows: [
        { id: 1, name: 'parent 1' },
        { id: 2, name: 'parent 2' },
        { id: 3, name: 'parent 3' }
        ],
        count: 3
        }
      • GET /api/parent/:id

        Server response:

        { id: 1, name: 'parent 1' }
    • Update:

      (Non of these endpoints affect the child fields)

      • PATCH /api/parent/:id - Update only parent fields included in the request body
      • PUT /api/parent/:id - Update all the parent fields and try to remove the fields that are not included in the request body
    • Delete:

      • DELETE /api/parent/:id - Try to delete the parent and errors if it is associated with any child
  • Child

    • Create:

      • POST /api/child

        Create child without parent: Not allowed

        Create child with associated parent:

        { name: 'child', parentId: 1 }
    • Read:

      • GET /api/child/:id

        Server response:

        {
        id: 1,
        name: 'child',
        parentId: 1,
        parent: {
        id: 1,
        name: 'parent 1'
        }
        }
    • Update:

      • PATCH /api/child/:id

        Change the associated parent:

        { parentId: 2 } // change the associated parent to 'parent 2'

        (NOTE: The aggregated parent fields cannot be updated through its child.)

      • DELETE /api/child/:id - Delete the child and disassociate it from its parent

Many-to-One

class Parent {
@NeededBy()
child: Child;
}
class Child {
@Needs()
parents: Parent[];
}
  • Child

    • Create:

      • POST /api/child/:id

        Create child without parents: Not allowed

        Create child with parents:

        {
        name: 'child',
        parents: [
        // Only id fields are needed
        { id: 1 },
        { id: 2 },
        { id: 3 }
        ]
        }
    • Read:

      • GET /api/child/:id

        Server response:

        {
        name: 'child',
        parents: [
        { id: 1, name: 'parents 1' },
        { id: 2, name: 'parents 2' },
        { id: 3, name: 'parents 3' }
        ]
        }
    • Update:

      • PATCH /api/child/:id

        Associate to new parents:

        {
        parents: [
        // Only id fields are needed
        { id: 4 },
        { id: 5 }
        ]
        }
      • PUT /api/child/:id

        Disassociate to all parents: Not allowed

        Associate and disassociate to parents:

        // Keeps the parent 1, associates to the parent 4 and disassociates to the others
        {
        name: 'child name',
        parent: [
        // Only id fields are needed
        { id: 1 },
        { id: 4 }
        ]
        }
    • Delete:

      • DELETE /api/child/:id - Delete the child and disassociate it from its parents

    (NOTE: The aggregated parent's fields are never updated through its child)

Knows

Knows one

class A {
@ForeignKey(() => B)
bId: number;
@Knows(() => B)
b: B;
}
  • Create:

    • POST /api/a

      Create A without associating it to any B:

      { name: 'a1' }

      Create A that knows a B:

      { name: 'a1', bId: 1 }
  • Read:

    • GET /api/a/:id

      Server response:

      {
      id: 1,
      name: 'a1',
      bId: 1,
      b: {
      id: 1,
      name: 'b1'
      }
      }
    • Update:

      • PATCH /api/a/:id

        Change the associated B:

        { bId: 2 } // change the associated B to 'b2'

        (NOTE: B's fields cannot be updated through A.)

  • Delete:

    • DELETE /api/a/:id - Delete an A and disassociate the deleted one to B

Knows many

class A {
@Knows(() => B)
bs: B[];
}
  • Create:

    • POST /api/a

      Create A without Bs:

      { name: 'a1', bs: [] }

      Create A with Bs:

      {
      name: 'a1',
      bs: [
      // Only id fields are needed
      { id: 1 },
      { id: 2 },
      { id: 3 },
      ...
      ]
      }
  • Read:

    • GET /api/a/:id

      Server response:

      {
      name: 'a1',
      bs: [
      { id: 1, name: 'b1' },
      { id: 2, name: 'b2' },
      { id: 3, name: 'b3' }
      ]
      }
  • Update:

    • PATCH /api/a/:id

      Associate to new Bs:

      {
      bs: [
      // Only id fields are needed
      { id: 4 },
      { id: 5 }
      ]
      }
    • PUT /api/a/:id

      Disassociate to all Bs:

      {
      name: 'a1',
      bs: []
      }

      Associate and disassociate to Bs:

      // Keeps b1, associates to b4 and disassociates to the other Bs
      {
      name: 'a1',
      bs: [
      // Only id fields are needed
      { id: 1 },
      { id: 4 }
      ]
      }
  • Delete:

    • DELETE /api/a/:id - Delete an A and all Bs that are associated with it will be disassociated