GatoGraphQL / GatoGraphQL

Interact with all your data in WordPress using GraphQL

Home Page:https://gatographql.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Further develop (and document) how the GraphQL API can help import data from an external site to the WordPress site

leoloso opened this issue · comments

The GraphQL API has a few features that make it easy to access the data from an external endpoint, manipulate it, and inject it into some other field or mutation, allowing a single GraphQL query to perform complex operations. For instance, it allows importing posts/users/categories/tags/etc from another site (whether it is WordPress or not) into the WordPress site, without the need to write custom resolvers!.

The procedure could be something like this:

  • A field rearrangeJSONObjectProperties($input: JSONObject, $fromToPropertyPaths: JSONObject) can manipulate the entries in an input, renaming the keys into the desired output
  • Via the "Resolved Field Variable Reference" feature, the output of the previous field can be accessed as an input into another field/mutation
  • Using the "Multiple Query Execution" feature we can export a JSONObject that is treated as the expected input type for some mutation (eg: PostInput, UserInput, etc)
  • In the subsequent query, check if the data already exists
  • If not, create it

For instance, this (potential) query accesses user data from an external REST endpoint, checks if the user exists on the local site and, if not, it creates it:

query ExportUserData
{
  externalData: restData(url: "https://some-other-site.com/rest/users")
  userData: rearrangeJSONObjectProperties(
    # Using "Resolved Field Variable Reference" to access some resolved value as an input to another field
    input: $externalData,
    fromToPropertyPaths: {
      "user.name": "name",
      "user.email": "email"
    }
  )
    # Using "Multiple Query Execution" to export a value
    @export(as: "userInput")
  extract(object: $userData, path: "email")
    @export(as: "userEmail")
}

query CheckUserExists($userEmail: String)
  @dependsOn(operation: "ExportUserData")
{
  userExists(userEmail: $userEmail) @export(as: "doesUserExist")
}

mutation CreateUser($doesUserExist: Boolean, $userInput: UserInput)
  @dependsOn(operation: "CheckUserExists")
  @execute(if: $doesUserExist)
{
  createUser(input: $userInput) {
    id
    name
    email
  }
}

Notice how $userInput is exported as a JSONObject, but is then treated as a UserInput in the following mutation. That casting of the type should already work.

Directives @dependsOn and @execute do not currently exist, but they can be implemented once "operation directives" are supported (currently they are not).

If the external endpoint is REST, a single rest field to get its data may be sufficient. If it is GraphQL, then using a new CPT called ExternalEndpoint might be better as to specify the GraphQL query:

query ExportUserData
{
  externalData: externalEndpointData(cptSlug: "some-graphql-external-endpoint-for-client")
  # ...
}