Skip to content

Commit 405707f

Browse files
committed
Focus on static methods
1 parent 747990a commit 405707f

2 files changed

Lines changed: 61 additions & 125 deletions

File tree

docs/developers/applications/index.md

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,14 @@ This guide is going to walk you through building a basic Harper application usin
8383

8484
[The getting started guide](/learn/) covers how to build an application entirely through schema configuration. However, if your application requires more custom functionality, you will probably want to employ your own JavaScript modules to implement more specific features and interactions. This gives you tremendous flexibility and control over how data is accessed and modified in Harper. Let's take a look at how we can use JavaScript to extend and define "resources" for custom functionality. In Harper, data is accessed through our [Resource API](../../reference/resources/), a standard interface to access data sources, tables, and make them available to endpoints. Database tables are `Resource` classes, and so extending the function of a table is as simple as extending their class.
8585

86-
To define custom (JavaScript) resources as endpoints, we need to create a `resources.js` module (this goes in the root of your application folder). And then endpoints can be defined with Resource classes that `export`ed. This can be done in addition to, or in lieu of the `@export`ed types in the schema.graphql. If you are exporting and extending a table you defined in the schema make sure you remove the `@export` from the schema so that don't export the original table or resource to the same endpoint/path you are exporting with a class. Resource classes have methods that correspond to standard HTTP/REST methods, like `get`, `post`, `patch`, and `put` to implement specific handling for any of these methods (for tables they all have default implementations). Let's add a property to the dog records when they are returned, that includes their age in human years. To do this, we get the `Dog` class from the defined tables, extend it (with our custom logic), and export it:
86+
To define custom (JavaScript) resources as endpoints, we need to create a `resources.js` module (this goes in the root of your application folder). And then endpoints can be defined with Resource classes that `export`ed. This can be done in addition to, or in lieu of the `@export`ed types in the schema.graphql. If you are exporting and extending a table you defined in the schema make sure you remove the `@export` from the schema so that don't export the original table or resource to the same endpoint/path you are exporting with a class. Resource classes have `static` methods that correspond to standard HTTP/REST methods, like `get`, `post`, `patch`, and `put` to implement specific handling for any of these methods (for tables they all have default implementations). Let's add a property to the dog records when they are returned, that includes their age in human years. To do this, we get the `Dog` class from the defined tables, extend it (with our custom logic), and export it:
8787

8888
```javascript
8989
// resources.js:
9090
const { Dog } = tables; // get the Dog table from the Harper provided set of tables (in the default database)
9191

9292
export class DogWithHumanAge extends Dog {
93-
static loadAsInstance = false;
94-
async get(target) {
93+
async static get(target) {
9594
const record = await super.get(target);
9695
return {
9796
...record, // include all properties from the record
@@ -126,8 +125,7 @@ The resource methods are automatically wrapped with a transaction and will autom
126125
//resource.js:
127126
const { Dog, Breed } = tables; // get the Breed table too
128127
export class DogWithBreed extends Dog {
129-
static loadAsInstance = false;
130-
async get(target) {
128+
static async get(target) {
131129
// get the Dog record
132130
const record = await super.get(target);
133131
// get the Breed record
@@ -145,7 +143,7 @@ The call to `Breed.get` will return a record from the `Breed` table as specified
145143
We may also want to customize access to this data. By default, the `target` has a `checkPermission` property that indicates that the table's `get` method will check if there is a valid user with access to a table before returning a record (and throw an `AccessViolation` if they do not). However, we can explicitly allow permission to the table's data/records by setting `checkPermission` to `false`:
146144

147145
```javascript
148-
async get(target) {
146+
static async get(target) {
149147
target.checkPermission = false;
150148
const record = await super.get(target);
151149
...
@@ -155,8 +153,7 @@ Here we have focused on customizing how we retrieve data, but we may also want t
155153
156154
```javascript
157155
export class CustomDog extends Dog {
158-
static loadAsInstance = false;
159-
async post(target, data) {
156+
static async post(target, data) {
160157
if (data.action === 'add-trick') {
161158
const record = this.update(target);
162159
record.tricks.push(data.trick); // will be persisted when the transaction commits
@@ -171,8 +168,7 @@ We can also define custom authorization capabilities here. For example, we might
171168
172169
```javascript
173170
export class CustomDog extends Dog {
174-
static loadAsInstance = false;
175-
async post(target, data) {
171+
static async post(target, data) {
176172
if (data.action === 'add-trick') {
177173
const context = this.getContext();
178174
// if we want to skip the default permission checks, we can turn off checkPermissions:
@@ -208,7 +204,7 @@ We can also directly implement the `Resource` class and use it to create new dat
208204
const { Breed } = tables; // our Breed table
209205
class BreedSource extends Resource {
210206
// define a data source
211-
async get(target) {
207+
static async get(target) {
212208
return (await fetch(`https://best-dog-site.com/${target}`)).json();
213209
}
214210
}

0 commit comments

Comments
 (0)