UNPKG

type-arango

Version:

ArangoDB Foxx decorators and utilities for TypeScript

152 lines (106 loc) 4.98 kB
# 📌 Example #3: Relations An example of working with relations in type-arango. Please have a look at the [basic example](../1-basic) first. Related attributes are decorated by [@OneToOne](../../API.md#onetoonetype-relation) or [@OneToMany](../../API.md#onetomanytype-relation). The [@Attribute](../../API.md#attributeschema-readers-writers) decorator can be omitted when the attribute does not store any data. However when the same attribute has a value, it is used to look up the related entity. Relations can either be fetched inside custom routes by using [entity.related('attribute')](../../API.md#entityrelatedattribute-keepattributes) or by simply providing the query parameter `relations` on default routes. ![divider](../../assets/divider.small.png) ### Example Setup ```ts import { Document, Entity, Entities, OneToMany, Related } from 'type-arango' @Document() class Author extends Entity { @Attribute() name: string @OneToMany(type => Book, Books => Books.author) books: Related<Book[]> @Attribute(type => number) @OneToMany(type => Book) favorites: Related<Book[]> } @Document() class Book extends Entity { @Attribute() title: string @Attribute(type => number) @OneToOne(type => Author) author: Related<Author> } // Authors [{ "_key": 1, "name": "Hermann Hesse", "favorites": [2,3] }, ...] // Books [{ "_key": 1, "title": "Steppenwolf", "author": 1 }, ...] @Collection(of => Author) @Route.GET({relations:['books']}) class Authors extends Entities {} @Collection({of: Book, relations: ['author'], routes: ['LIST']}) class Books extends Entities {} ``` The code above creates the collections Authors and Books. Both collections have a route (Author GET & Books LIST) and expose a single relation. **Note:** it does not matter whether the routes are created by using the [@Collection(options)](../../API.md#collectionofdocument-options) or additional [@Route.*](../../API.md#routegetpath-schema-roles-summary-options) decorators. ![divider](../../assets/divider.small.png) ### Load relations from the client side The `relations` property of the `@Collection` decorator indicates which of the available relations can be exposed by the routes. For example, the route `GET authors` can optionally return all `books` of the author when called with the query parameter `relations=books`. The property can be set on a collection basis (with [CollectionOpt](../../API.md#collectionofdocument-options)) and or for ever route by using [RouteOpt](../../API.md#routeopt). ![divider](../../assets/divider.small.png) ### Example Requests Fetching all Books, their Authors and their favorite books: ``` GET ../books?relations=author,author.favorites [ { "_key": 1, "title": "Steppenwolf", "author": { "_key": 1, "name": "Hermann Hesse", "favorites": [Book2, Book3] // you get the point } } ] ``` Note: Use `attributes=book.name` to omit all other attributes from the response. ![divider](../../assets/divider.small.png) ### Custom route type-arango provides the method `related` for loading related & exposed entities inside custom routes. The following example appends all authors to the books in case the client requests them by providing the query parameters `relations=author`. ```ts @Collection(of => Book) class Books extends Entities { @Route.GET('custom', {relations:'author'}) static GET_CUSTOM({relations}: RouteArg){ const book = Books.find(1) return relations(book) } } ``` ![divider](../../assets/divider.small.png) #### Virtual relations Virtual relations are the simplest type of relations. They don't require any information to be stored, and the attribute does not exist in the database - therefore the `@Attribute` decorator is not used. #### Link relations Link relations are attributes containing either a single or a list of references to the related document/s. ### Tuple link relations The values of link relations can be tuples `[KEY, VALUE]` containing an additional value, which will be merged with the related document within `_value`: ``` { "ratings": [ [ 2, { stars: 5 } ], [ 5, { stars: 3 } ] ] } // The computed value will be merged with the related document as `_value`: { "ratings": [ { ...DOCUMENT(2), _value: { stars: 5 } }, { ...DOCUMENT(5), _value: { stars: 3 } } ] } ``` > Note: Make sure to define the attribute `_value` and it's permissions on the related document schema, otherwise the value will be stripped. ![divider](../../assets/divider.small.png) ### Documentation All relations are automatically documented within the swagger docs of the ArangoDB Web Interface. ![divider](../../assets/divider.png)