AgentSkillsCN

graphile-v5-presets

创建并组合PostGraphile v5预设。当被要求“创建预设”、“配置PostGraphile”、“合并预设”、“禁用插件”,或在搭建全新的PostGraphile v5服务器时,此功能将为你提供便捷高效的解决方案。

SKILL.md
--- frontmatter
name: graphile-v5-presets
description: Create and compose PostGraphile v5 presets. Use when asked to "create a preset", "configure PostGraphile", "combine presets", "disable plugins", or when setting up a new PostGraphile v5 server.
compatibility: PostGraphile v5+, graphile-config
metadata:
  author: constructive-io
  version: "1.0.0"

PostGraphile v5 Presets

Create and compose PostGraphile v5 presets for configuring your GraphQL API.

Official Documentation

When to Apply

Use this skill when:

  • Setting up a new PostGraphile v5 server
  • Creating a custom preset that combines multiple features
  • Disabling unwanted default plugins
  • Configuring schema options

Quick Start

Basic Preset Structure

typescript
import type { GraphileConfig } from 'graphile-config';

export const MyPreset: GraphileConfig.Preset = {
  // Extend other presets
  extends: [
    OtherPreset,
  ],
  
  // Add plugins
  plugins: [
    MyPlugin,
  ],
  
  // Disable plugins by name
  disablePlugins: [
    'PluginToDisable',
  ],
  
  // Schema configuration
  schema: {
    // Schema options here
  },
  
  // Grafserv (HTTP server) configuration
  grafserv: {
    port: 5433,
    graphqlPath: '/graphql',
    graphiqlPath: '/graphiql',
  },
};

Preset Composition

Extending Multiple Presets

Presets are merged in order - later presets override earlier ones:

typescript
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber';
import { PostGraphileConnectionFilterPreset } from 'postgraphile-plugin-connection-filter';

export const MyPreset: GraphileConfig.Preset = {
  extends: [
    PostGraphileAmberPreset,           // Base preset
    PostGraphileConnectionFilterPreset, // Adds filter plugin
    MinimalPreset,                      // Our customizations
    InflektPreset,                      // Custom inflection
  ],
};

Creating a Composable Preset

Make your preset easy to combine with others:

typescript
// Good: Single-purpose preset
export const NoRelayPreset: GraphileConfig.Preset = {
  disablePlugins: [
    'NodePlugin',
    'PgTableNodePlugin',
  ],
};

// Good: Preset that adds one feature
export const FilterPreset: GraphileConfig.Preset = {
  extends: [PostGraphileConnectionFilterPreset],
  schema: {
    connectionFilterRelations: false,
  },
};

// Then combine them
export const MyAppPreset: GraphileConfig.Preset = {
  extends: [
    PostGraphileAmberPreset,
    NoRelayPreset,
    FilterPreset,
  ],
};

Disabling Plugins

By Plugin Name

Use disablePlugins array with plugin names as strings:

typescript
export const MinimalPreset: GraphileConfig.Preset = {
  disablePlugins: [
    // Node/Relay plugins
    'NodePlugin',
    'AddNodeInterfaceToSuitableTypesPlugin',
    'NodeIdCodecBase64JSONPlugin',
    'NodeIdCodecPipeStringPlugin',
    'RegisterQueryNodePlugin',
    'NodeAccessorPlugin',
    'PgNodeIdAttributesPlugin',
    'PgTableNodePlugin',
    
    // Connection filter relation plugins
    'PgConnectionArgFilterBackwardRelationsPlugin',
    'PgConnectionArgFilterForwardRelationsPlugin',
  ],
};

Finding Plugin Names

Plugin names are the name property of the plugin object. Check the source code or use the InflectorLoggerPlugin to see what's being generated.

Schema Configuration

Common Schema Options

typescript
export const MyPreset: GraphileConfig.Preset = {
  schema: {
    // Connection filter options
    connectionFilterRelations: false,
    connectionFilterComputedColumns: false,
    connectionFilterSetofFunctions: false,
    connectionFilterLogicalOperators: true,
    connectionFilterArrays: true,
    
    // Other schema options
    pgJwtSecret: process.env.JWT_SECRET,
    pgDefaultRole: 'app_anonymous',
  },
};

Server Configuration

Grafserv Options

typescript
export const MyPreset: GraphileConfig.Preset = {
  grafserv: {
    port: 5433,
    graphqlPath: '/graphql',
    graphiqlPath: '/graphiql',
    websockets: true,
    watch: process.env.NODE_ENV === 'development',
  },
};

Using Presets

With makePgService

typescript
import { postgraphile } from 'postgraphile';
import { makePgService } from 'postgraphile/adaptors/pg';
import { MyPreset } from './preset';

const preset: GraphileConfig.Preset = {
  extends: [MyPreset],
  pgServices: [
    makePgService({
      connectionString: process.env.DATABASE_URL,
      schemas: ['public', 'app'],
    }),
  ],
};

const pgl = postgraphile(preset);

With Express

typescript
import express from 'express';
import { createServer } from 'http';
import { postgraphile } from 'postgraphile';
import { grafserv } from 'postgraphile/grafserv/express/v4';

const app = express();
const server = createServer(app);

const pgl = postgraphile(preset);
const serv = pgl.createServ(grafserv);

await serv.addTo(app, server);

server.listen(5433, () => {
  console.log('Server running on http://localhost:5433');
});

Complete Example

typescript
import type { GraphileConfig } from 'graphile-config';
import { PostGraphileAmberPreset } from 'postgraphile/presets/amber';
import { PostGraphileConnectionFilterPreset } from 'postgraphile-plugin-connection-filter';
import { makePgService } from 'postgraphile/adaptors/pg';

// Custom plugins
import { MinimalPreset } from './plugins/minimal-preset';
import { InflektPreset } from './plugins/custom-inflector';
import { PrimaryKeyOnlyPreset } from './plugins/primary-key-only';

export const ConstructivePreset: GraphileConfig.Preset = {
  extends: [
    MinimalPreset,                      // No Node/Relay
    InflektPreset,                      // Custom naming
    PrimaryKeyOnlyPreset,               // Only PK lookups
    PostGraphileConnectionFilterPreset, // Filter plugin
  ],
  disablePlugins: [
    'PgConnectionArgFilterBackwardRelationsPlugin',
    'PgConnectionArgFilterForwardRelationsPlugin',
  ],
  schema: {
    connectionFilterRelations: false,
    connectionFilterComputedColumns: false,
  },
};

// Usage
const preset: GraphileConfig.Preset = {
  extends: [ConstructivePreset],
  pgServices: [
    makePgService({
      connectionString: process.env.DATABASE_URL,
      schemas: ['public'],
    }),
  ],
  grafserv: {
    port: 5433,
    graphqlPath: '/graphql',
    graphiqlPath: '/graphiql',
  },
};

Troubleshooting

IssueSolution
Plugin not disabledCheck exact plugin name (case-sensitive)
Preset not appliedVerify extends order (later overrides earlier)
Schema option ignoredSome options require specific plugins to be enabled
Type errorsEnsure graphile-config types are installed

References

  • PostGraphile v5 Configuration Docs: https://postgraphile.org/postgraphile/next/config
  • See graphile-v5-minimal skill for disabling Node/Relay
  • See graphile-v5-behaviors skill for controlling what gets generated
  • See graphile-v5-plugins skill for creating custom plugins
  • See graphile-v5-debugging skill for graphile config print CLI command