Proca Server API

Proca Server uses a GraphQL API at an endpoint /api for a HTTP connection or /socket for a WebSocket connection. You will need WebSocket to run subscription operations with GraphQL, however, for Proca Server the HTTP API is usually enough (currently there is 1 subscription operation).

If you develop for node, you can use @proca/api library to create a configured GraphQL client (using urql library). Note you can use any graphql client instead but @proca/api has some helpers and can talk to Phoenix WebSocket (Absinthe) if you need subscription support.

GraphQL provides a discoverable API, which you can explore in the playground at /graphiql endpoint (example), or using a GraphQL client of choice.

To visually explore the API, go to GraphQL Voyager, click change schema and paste all of schema.graphql into SDL tab.

API schema visualized

The API reference is available here and also visible in schema inspector in GraphiQL.

Authentication and security context

All operations run in some user context:

  • Anonymous
  • Authenticated - an User is assigned to the opration based on one of authentication methods, and optionally a current organisation - they form a security context.

authentication methods

Use Authorization header to authenticate the operation. We support:

  • HTTP Basic Auth header with email + password: Authorization: Basic base64-encoded-user:password
  • API token - generated by Proca Server for a user (create it with resetApiToken mutation): Authorization: Bearer API-XXXXXXX
  • JWT token - if configured; tested with Zero Trust Proxy and GoTrue/Supabase: Authorization: Bearer eyJWT-token-JWTJWTJWTJWTJWTJWTJWT

Errors

Errors are returned as a list of GraphQL errors, each consisting of a human readable message, path specifying which input value causes a problem, and extensions object, which has a machine readable error code.

Example query with basic authenticate

Consider this TypeScript code. It creates a connection using HTTP Basic Auth using helpers from @proca/api library. Then it runs a query to fetch current, authenticated user. We recommend to use GraphQL Codegen to create a typed query documents from foo.graphql files. This will provide you with typed responses from the API and ease unpacking returned objects.

import "cross-fetch/polyfill" // for missing fetch() in node...
import {httpLink, basicAuth} from '@proca/api'

const whoami = async (email : string, pwd : string) => {
  const client = httpLink('https://api.proca.app', basicAuth({username: email, password: pwd}));

  const query = `
    query CurrentUserOrgs {
      currentUser {
        email roles { role org {name title} }
      }
    }`
  const {data, error} = await client.query(query, {}).toPromise()

  if (error?.graphQLErrors[0]?.extensions?.code === 'unauthorized') {
    console.error("Bad credentials")
    return
  }

  const myOrgs = data.currentUser.roles.map(({title})=>title).join(', ')
  console.log(`I am ${data.currentUser.email}`)
  console.log(`I am member of these orgs: ${myOrgs}`)
}