Skip to main content
Version: 4.12.0

Namespaces (PostgreSQL "schemas")

In PostgreSQL, each database consists of a number of "schemas". The default schema is named "public" and many users only ever deal with this one schema.

In PostGraphile we advise you to use schemas to help organise your application - you can use one schema for the tables that will be exposed to GraphQL, another for the tables that should be completely private (e.g. where you store the bcrypted user passwords or other secrets never to be exposed!), and you can use other schemas too, whatever makes sense for your application.

To create a schema in PostgreSQL:

CREATE SCHEMA app_public;

To create or reference something in that schema, just prepend the name of the thing with the schema name, e.g:

CREATE TABLE app_public.users ( ... );
CREATE FUNCTION app_public.best_user() ...;

SELECT * FROM app_public.users;
SELECT * FROM app_public.best_user();


Having built quite a few applications on PostGraphile now, I (Benjie) have settled on the following:

  • app_public - tables and functions to be exposed to GraphQL (or any other system) - it's your public interface. This is the main part of your database.
  • app_hidden - same privileges as app_public, but it's not intended to be exposed publicly. It's like "implementation details" of your app_public schema. You may not need it often.
  • app_private - SUPER SECRET STUFF 🕵️ No-one should be able to read this without a SECURITY DEFINER function letting them selectively do things. This is where you store passwords (bcrypted), access tokens (hopefully encrypted), etc. It should be impossible (thanks to RBAC (GRANT/REVOKE)) for web users to access this.

I personally don't use the public schema for anything other than as the default location that PostgreSQL extensions get installed.

Using this pattern is not required and in fact you can just use the default public schema if you so chose. By default, PostGraphile will automatically ignore resources installed by extensions, so you don't need to omit these manually. Other tables and functions can be omitted using the smart comments functionality.

Other schemas

Here's some other schemas you might see (but should not modify):