Postgraphile client for react-admin
Typescript API: https://bowlingx.github.io/ra-postgraphile/
$ yarn add ra-postgraphile / npm install ra-postgraphile --save
The ra-postgraphile
data provider accepts 2 arguments:
client
- The ApolloClient
instance to use.
config
- optional configuration
pgDataProvider(client, [config])
The following examples shows the basic usage:
import React, { useEffect, useState } from 'react'
import { Admin, Resource } from 'react-admin'
import { useApolloClient } from '@apollo/react-hooks'
import pgDataProvider from 'ra-postgraphile'
import { PostList, PostEdit, PostCreate } from './posts'
import { CommentList, CommentEdit, CommentCreate } from './posts'
const App = () => {
const [dataProvider, setDataProvider] = useState(null)
const client = useApolloClient()
useEffect(() => {
;(async () => {
const dataProvider = await pgDataProvider(client)
setDataProvider(() => dataProvider)
})()
}, [])
return (
dataProvider && (
<Admin dataProvider={dataProvider} layout={Layout}>
<Resource name="Posts" list={PostList} edit={PostEdit} create={PostCreate} />
<Resource name="Comments" list={CommentList} create={CommentCreate} edit={CommentEdit} />
</Admin>
)
)
}
export default App
The project has been tested only with the following plugins enabled on postgraphile
:
There is limited support for the postgis
plugin and not all input/query types are properly mapped.
const PgSimplifyInflectorPlugin = require('@graphile-contrib/pg-simplify-inflector')
const PgConnectionFilterPlugin = require('postgraphile-plugin-connection-filter')
Please see src/__test_utils/QueryRunner.ts for a minimal example setup.
For full-text search capabilities, the following plugin is also required:
const PostGraphileFulltextFilterPlugin = require('postgraphile-plugin-fulltext-filter')
You can pass an optional configuration object:
const pgDataProviderConfig: ProviderOptions = {
typeMap: {
YourType: {
expand: true,
},
},
}
typeMap
- allows you to configure complex types and how they should be handled.
Please see (src/defaultTypeConfig.ts) for a default mapping.
Your config will be merged with the defaults.The following can be configured
Option | Signature | Description |
---|---|---|
queryValueToInputValue |
(value: any ) => any |
Allows you to map the value if used as an input type for mutations. Some values might not convert 1:1 if returned from the query and used as an input |
excludeFields |
string[] or ((fieldName: string, queryFetchType: FetchQueryType) => boolean) |
Allows you to exclude certain fields, either by passing an array (e.g. ['field1', 'field2'] ) or a function |
includeFields |
string[] or ((fieldName: string, queryFetchType: FetchQueryType) => boolean) |
Same as exclude fields, but if provided will let you dynamically decide if a field is queried. |
computeArgumentsForField |
(fieldName: string, args: ReadonlyArray<IntrospectionInputValue> ) => Record< string, any> or null |
Allows you to dynamically provide arguments for a given field |
expand |
boolean |
If true, will expand this type and query subfields |
pluralize |
(value: string ) => string |
Optional pluralization of resource name (uses pluralize by default) |
Please see (src/types.ts) for detailed types of TypeConfig
.
If you require support for apollo-client
v2 please use version <6
, otherwise use >=6
.
I recommend to upgrade to @apollo/client
v3 packages because the core graphql data provider
requires version 3 in it's latest versions.
ra-postgraphile
works on graphql types that are exposed by postgraphile
.
We currently support the following constructs to query data:
Tables
Views
Functions
with custom return type.Please see here for an example schema.
react-admin
requires each resource to be identified by a unique id
. If your resource does not
have an id
field,
we alias the id field to your primaryKey
. All types processed by ra-postgraphile
require a
primary key.
The library will use the postgraphile-plugin-connection-filter
filter property by default to apply
filters specified (e.g. for <List filters={...} />
).
Type | example filter |
---|---|
string |
{ includes: 'value'} |
array |
{ in: [1,2,3] } |
numeric |
{ equalTo: 100 } |
boolean |
{ equalTo: true } |
...others |
{ equalTo: 'ENUM' } |
Multiple fields will then be merged with and
and send to postgraphile
e.g.:
{
"and": [
{
"field": {
"includes": "value"
}
}
]
}
To customize a filter, you have to provide a parse
and format
function to the actual input
Component. You can then customize the filter operation:
import type { FilterSpec } from 'ra-postgraphile'
const startsWithInsensitive = {
parse: (value: string): FilterSpec => {
return {
operator: 'startsWithInsensitive',
value,
}
},
format: (v: FilterSpec) => v?.value || '',
}
const Filters = (props: Record<string, unknown>) => (
<Filter {...props}>
<TextInput label="Search" source="name" alwaysOn {...startsWithInsensitive} />
</Filter>
)
This will then be transformed to
{
"and": [
{
"field": {
"startsWithInsensitive": "value"
}
}
]
}
It's also possible to define multiple filters per field to create nested filters
const filterThatFiltersMultipleFields = {
parse: (value: string) => ({
value: value
? [
{
firstKey: { every: { someReferenceId: { equalTo: value } } },
secondKey: { every: { someReferenceId: { equalTo: value } } },
},
]
: {},
key: 'or' /* can be or, and etc... */,
}),
format: (value: any) => value?.value?.[0]?.firstKey?.every?.someReferenceId?.equalTo,
}
This will be transformed to a filter like
{
"and": [
{
"or": [
{
"firstKey": {
"every": {
"someReferenceId": {
"equalTo": "value"
}
}
},
"secondKey": {
"every": {
"someReferenceId": {
"equalTo": "value"
}
}
}
}
]
}
]
}
We are using yarn
for package management.
To run all tests you have to start the dependent postgres container with docker-compose up -d
.
Generated using TypeDoc