GraphQL by PoP

CMS-agnostic GraphQL server in PHP

Get Started →

Designed for optimal experience


Queries are resolved in linear time on the number of types involved


Resolvers deal with IDs (instead of objects), removing the need to implement batching/deferred


Types have their resolvers attached by injection, and resolvers can override each other


The engine is based on executing directives, allowing any type of custom functionality

# Query what you need. Get predictable results

Send a GraphQL query to your API and get exactly the data you need.

query PostsWithComments {
  posts {
    comments {
      author {

The response from the API always mirrors the GraphQL query.

  "data": {
    "posts": [
        "title": "Hello world!",
        "comments": [
            "date": "2020-04-08",
            "content": "Check us out!",
            "author": {
              "name": "Leo"

Rock-solid architecture

⧐ Code-first approach ⧏

The schema is generated from code. Work with your teammates concurrently on the schema without conflicts, without tooling, and without bureaucracy.

⧐ Dynamic schema ⧏

The resolvers attach themselves to the types. Each field can be handled by different resolvers, and the chosen one is selected on runtime, depending on the context.

⧐ Public/private schema managed through ACLs ⧏

From a single source of truth, expose different schemas for different users, managing it through Access Control Lists based on the user being logged-in or not, roles, capabilities, or custom rules.

⧐ Field/directive-based versioning ⧏

In addition to evolving the GraphQL schema, every field and directive can be independently versioned, and the specific version to use is chosen through field/directive arguments in the query.

⧐ Robust caching ⧏

Cache the response from the query in several layers (server, CDN, etc) using standard HTTP caching, defining the max age field by field. Cache the results from expensive operations in disk or memory, defining the expiry time field by field.

⧐ Nested mutations ⧏

Perform mutations on every type, not just on the root type, and have a mutation be executed on the result from another mutation. The schema gets neater and slimmer!

⧐ Automatic namespacing ⧏

No need to worry if different teams or 3rd party providers using the same names for their types and interfaces. Create neater schemas by removing the 'MyCompanyName' prefix from your types, you won't need it.

⧐ Proactive warnings/deprecations ⧏

Issues with the query are shown in the response to the query, and not just when doing introspection. Avoid your users from never finding out that your schema has been upgraded!


The Gato GraphQL plugin brings all the power of GraphQL by PoP into your WordPress site

# Superpower your API

Superpower your API