Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Documentation for ApplyTransforms, and Add Resources to Each and PgSelect Docs #2163

Merged
merged 5 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions grafast/website/grafast/step-library/dataplan-pg/pgSelect.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,11 @@ expect, instead it uses a tuple with entries for each of the selected
attributes. The makeup of this tuple will vary depending on which attributes
you requested, and in which order, so you must not rely on its structure. To
get an attribute you should use `$pgSelectSingle.get(attr)` or similar

## Using the Underlying Data of a PgSelect Step

Although PgSelect is an opaque step, there are a few ways to modify the keys and values of that are returned in the plan.

For altering the returned keys of the object, see the documentation for [`each`](../standard-steps/each.md)

For altering the values of the returned object, see the documentation for [`applyTransforms`](../standard-steps/applyTransforms.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# applyTransforms

Takes a step as the first argument and returns a step that guarantees all `listItem` transforms have occurred.

This step is useful for when you need all of:

- the `listItem` transforms to have already taken place (e.g. you're going to
- send the result to an external service) rather than processing them through
- the GraphQL response

This is very useful for modifying the values of an opaque step!

## Type

```ts
function applyTransforms($step: ExecutableStep): ExecutableStep<any>;
```

### Example

Let's say you have a `PgSelect` step and you want to apply logic to the values of said step. You may be inclined to do something like this:

```ts
const $users = usersResource.find();
const tbl = $users.alias;
$users.where(sql`${tbl}.username = 'Benjie'`);
// Options that could be used here include: loadOne, loadMany, lambda
return lambda(
$users,
(users) => {
return users.map((user) => ({
username: "USER-" + user.username,
...user,
}));
},
true,
);
```

Due to `PgSelect` being an opaque step, this will not work! The values of `$users` will not be loaded by the time the `lambda` step is run. In order to guarantee that those values are available, you can wrap the `$users` step in an `applyTransforms`!

```ts
const $users = usersResource.find();
const tbl = $users.alias;
$users.where(sql`${tbl}.username = 'Benjie'`);
// By using applyTransforms, it guarantees these values will be available
return lambda(
applyTransforms($users),
(users) => {
return users.map((user) => ({
username: "USER-" + user.username,
...user,
}));
},
true,
);
```
33 changes: 33 additions & 0 deletions grafast/website/grafast/step-library/standard-steps/each.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,36 @@ Usage:
```ts
const $newList = each($oldList, ($listItem) => doSomethingWith($listItem));
```

## Extended Usage with `object`

You may end up in a scenario where you need to alter the return value of an opaque step. For example, when using a `PgSelect` step, you may end up with something like this in your plan:

```ts
const $users = usersResource.find();
const tbl = $users.alias;
$users.where(sql`${tbl}.username = 'Benjie'`);
benjie marked this conversation as resolved.
Show resolved Hide resolved
return $users;
```

For this example, lets say you have a field you want to resolve to with a type that does not match the schema of the DB:

```graphql
type UsernameMapping {
currentUsername: String!;
currentEmail: String!;
}

```

In order to map these values to new keys, you could use something like this:

```ts
// return $users;
return each($users, ($user) =>
object({
currentUsername: $user.get("username"),
currentEmail: $user.get("email"),
}),
);
```