Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/graphile-contrib/postgraphile-plugin-derived-field

Add derived fields in PostGraphile
https://github.com/graphile-contrib/postgraphile-plugin-derived-field

Last synced: 12 days ago
JSON representation

Add derived fields in PostGraphile

Awesome Lists containing this project

README

        

[![Package on npm](https://img.shields.io/npm/v/postgraphile-plugin-derived-field.svg)](https://www.npmjs.com/package/postgraphile-plugin-derived-field) [![CircleCI](https://circleci.com/gh/graphile-contrib/postgraphile-plugin-derived-field.svg?style=svg)](https://circleci.com/gh/graphile-contrib/postgraphile-plugin-derived-field)

# postgraphile-plugin-derived-field

This plugin provides an interface for adding derived fields to the schema generated by PostGraphile v4.

The term "derived fields" is used to differentiate this approach from the standard [Computed Columns](https://www.graphile.org/postgraphile/computed-columns/) support in PostGraphile. This plugin effectively adds "computed columns in JavaScript" to your toolbelt.

## Getting Started

Define your derived fields in the `derivedFieldDefinitions` property of `graphileBuildOptions`:

``` js
const express = require("express");
const { postgraphile } = require("postgraphile");
const PostGraphileDerivedFieldPlugin = require("postgraphile-plugin-derived-field");

const app = express();

app.use(
postgraphile(pgConfig, schema, {
graphiql: true,
appendPlugins: [PostGraphileDerivedFieldPlugin],
graphileBuildOptions: {
derivedFieldDefinitions: [
// your definitions here
]
}
})
);

app.listen(5000);
```

Provide `derivedFieldDefinitions` as an array of objects with the following structure:

```
{
identifiers: Array,
inflect: function,
resolve: function,
type?: string | build => T,
description?: string
}
```
The Scenarios section below provides guidance on structuring `identifiers`, `inflect`, and `resolve` for your specific use case.

Use `type` to specify the GraphQL type that the `resolve` function returns. This can be a string identifying the GraphQL type name, or a function (with the `build` helper available as the first argument) that returns a GraphQL type. Default: String

Use `description` to populate the field description in the schema.

## Scenarios

### Derive a new field from one database column

``` js
{
identifiers: [
{
table: "my_schema.my_table",
columns: ["my_column"],
},
],
inflect: fieldName => `derivedFrom${fieldName}`,
resolve: val => `Value derived from ${val}`,
}
```

### Derive a new field from multiple database columns

``` js
{
identifiers: [
{
table: "my_schema.my_table",
columns: ["my_column", "my_other_column"],
},
],
inflect: (...fieldNames) =>
`derivedFrom${fieldNames.map(upperFirst).join("And")}`,
resolve: (my_column, my_other_column) =>
`Value derived from ${my_column} and ${my_other_column}`,
}
```

### Derive a new field from columns that have a specific tag

This approach uses the "smart comments" feature of PostGraphile to match columns that have been assigned a specific tag.

``` js
{
identifiers: [
{
tag: "mytag",
},
],
inflect: fieldName => `derivedFrom${fieldName}`,
resolve: val => `Value derived from ${val}`,
}
```

## Alternative syntax

Column names can be provided as a string: `"my_schema.my_table.my_column"`. This syntax does not support generating a derived field from multiple database columns.

Tag names can be provided as a string: `"@mytag"`

## Examples

Generate pre-signed URLs for client-side S3 GET requests

``` js
const express = require("express");
const { postgraphile } = require("postgraphile");
const PostGraphileDerivedFieldPlugin = require("postgraphile-plugin-derived-field");

const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const bucket = "postgraphile-plugin-test";

const app = express();

app.use(
postgraphile(pgConfig, schema, {
graphiql: true,
appendPlugins: [PostGraphileDerivedFieldPlugin],
graphileBuildOptions: {
derivedFieldDefinitions: [
{
identifiers: ["my_schema.my_table.my_column"],
inflect: fieldName => `${fieldName}SignedUrl`,
resolve: val => s3.getSignedUrl('getObject', {Bucket: bucket, Key: val, Expires: 900})
}
]
}
})
);

app.listen(5000);
```