Homepage

Persisting Part of a Third-Party API Response

Last edit: Dec 28, 2023

This guide will help you persist part of a third-party API response by walking you through an example.

Warning

This article is deprecated. The easiest way to work with third party api is to invoke api calls via mutation, which would return a response, and then use liquid to implement business rules based on the response

Requirements

This is an advanced tutorial. To follow it, you should be familiar with basic platformOS concepts, HTML, GraphQL queries, Liquid, YAML, and the topics in the Get Started section, especially topics related to pages, users, and notifications.

Steps

Persisting part of a third-party API response is a seven-step process:

Step 1: Create profile and Property

Create a new user profile called test_profile, and create a Property to store the value from the API, called third_party_api_value:

app/user_profile_types/default.yml
name: test_profile
properties:
- name: third_party_api_value
  type: string

Step 2: Create test endpoint

Create a test endpoint that simulates a third-party API JSON response:

app/views/pages/test-endpoint.json.liquid

{
  "third_party_api_id": "id-1"
}

Step 3: Create API Call Notification

Create an API Call Notification that should:

  1. send a request to https://<your_domain>.com/test-endpoint.json
  2. store the value from the response in a property

Replace example.com with your domain:

app/api_calls/send_request.liquid

---
name: send_request
to: http://example.com/test-endpoint.json
format: http
request_type: GET
callback: "{%- assign response_json = response.body | to_hash -%}{% graphql res = 'persist_in_custom_attribute', user_id: form.id, third_party_api_id: response_json.third_party_api_id %}"
request_headers: '{
  "Content-Type": "application/json"
}'
---
{
  "id": "{{ form.id }}"
}

Step 4: Create GraphQL mutation

In the callback, the graphql tag invokes a GraphQL mutation with the provided arguments. The query accepts two arguments: the user_id, the ID of the user we want to update, and the third_party_api_id which is the value we want to store. The content of the GraphQL mutation file:

app/graphql/persist_in_custom_attribute.graphql
mutation persist_in_custom_attribute($user_id: ID!, $third_party_api_id: String!) {
  user_update(
    id: $user_id,
    user: {
      profiles: [
        {
          name: "test_profile"
          values: { properties: [{ name: "third_party_api_value", value: $third_party_api_id }] }
        }
      ]
    }
    form_name: "callback_persist_in_custom_attribute"
  ) {
    id
  }
}

The mutation passes the arguments to a form called callback_persist_in_custom_attribute. Make sure that its configuration includes the fields you want to persist. Please note: by re-using an idea of form here, you can easily send additional emails, SMSes, or even other API calls. All you want to do in this example though is to store the value, so you don't have to add any extra notifications.

app/forms/callback_persist_in_custom_attribute.liquid
---
name: callback_persist_in_custom_attribute
async_callback_actions:
resource: User
fields:
  profiles:
    test_profile:
      properties:
        third_party_api_value:
---

Step 5: Create page to embed form

Once you have an API Call Notification defined, you should associate it with a form to trigger it. Create a page for embedding this form.

app/views/pages/test-form.liquid

{% include_form 'test_form', object_id: current_user.id, object_class: 'User' %}

Step 6: Create and embed form

Create the form and associate it with the API Call Notification. It can be a signup form, that creates the test_profile in the background:

app/forms/test-form.liquid
---
name: test_form
resource: User
fields:
  email:
  password:
  profiles:
    test_profile:
      enabled:
redirect_to: /test-result
api_call_notifications:
  - send_request
---

{% form url: "/api/users/{{ current_user.id }}" %}
  <label for="email">Email</label>
  <input name="{{ form.fields.email.name }}" value="{{ form.fields.email.value}}" id="email" type="email">

  <label for="password">Password</label>
  <input name="{{ form.fields.password.name }}" id="password" type="password">
  {% if form.errors.password %}
    <p>{{ form.errors.password }}</p>
  {% endif %}

  <input name="{{ form.fields.profiles.test_profile.enabled.name }}" value="1" type="hidden">

  <button>Save</button>
{% endform %}

Once the user fills the signup form without validation errors, the system will proceed to trigger the API Call Notification. If it is successful, it will trigger the callback, in which you will have access to the server's response via the response variable. You will be able to access various things, like response.code, and the most important, response.body. The callback will run the GraphQL mutation, which will use form to persist the data.

Step 7: Display results

In the test_form you have set up a redirection to /test-result, so create this page and make it display the third_party_api_value:

app/views/pages/test-result.liquid

{% graphql graph_current_user = 'get_current_user_third_party_api_value'  %}
Third Party Api Value: for {{ graph_current_user.current_user.email }}: {{ graph_current_user.current_user.test_profile.third_party_api_value }}

which uses the following GraphQL query:

app/graphql/get_current_user_third_party_api_value.graphql
query get_current_user_third_party_api_value {
  current_user {
    email
    test_profile: profile(profile_type: "test_profile") {
        third_party_api_value: property(name: "third_party_api_value")
    }
  }
}

You can now go to the /test-form page, provide sign up details, and click the Save button. Initially, the correct value will not be there because the API call is triggered in the background, outside of the request lifecycle. This is important to not rely on a third-party API's availability. However, when you refresh after a couple of seconds, the value has been populated.

Questions?

We are always happy to help with any questions you may have.

contact us