LogoLogo
Siteglide.comAdminRoadmap
  • 👋Welcome
  • Get Started
    • 🚀Quickstart Guides
    • ❔Support & FAQs
      • â„šī¸Siteglide Support Policy
      • â„šī¸Siteglide Technology Stack
      • â„šī¸External Resources
      • â„šī¸Front-end Browser Support
  • Portal
    • Account
    • Sites
      • 🚀Quickstart: Create a Site
      • â„šī¸Site Details
      • â„šī¸Site Users
      • 📋Install & Manage Modules
      • đŸ’ŗGo Live
      • đŸ’ŗSubscription
      • 🌍Domains
        • 📋Add a Fully Delegated Domain
        • 📋Add an External Domain
        • đŸ’ģSubdomain on a separate instance
        • 📋How to setup a multi domain start page
      • â˜ī¸Site Backups and Disaster Recovery
    • Users
      • 📋User Roles
      • 📋Invite & Manage Users
    • Billing
      • đŸ’ŗBilling Setup
      • đŸ’ŗSubscriptions and Changes
      • đŸ’ŗAutomatic Site Upgrades
      • đŸ’ŗInvoices
    • Tickets
    • Marketplace
    • Agencies
      • 👩‍đŸ’ģAgency Account
      • 👩‍đŸ’ģClients
      • 👩‍đŸ’ģSite Copies
      • 👩‍đŸ’ģAgency Whitelabelling
  • Developer Tools
    • CLI
      • 🚀Quickstart: CLI
      • â„šī¸About
      • 📋Site Setup
      • ❔Troubleshooting
      • đŸ’ģReference
      • đŸ›ŗī¸CLI Changelog
      • đŸ§™â€â™‚ī¸Go Further: CLI
        • Creating WebApps via CLI
    • Liquid
      • â„šī¸About
      • đŸ’ģReference
      • Accessing Data in Liquid Variables - Tutorial 1 - Using Dot Notation
      • Accessing Data in Liquid Variables - Tutorial 2 - Iterating over Arrays and Objects
      • Using Collections with WebApps and Modules
      • Accessing Data from the Global Context Variable
      • Truthiness - Using Liquid to determine if a field is empty or blank
      • 📋Alternatives to Storing and Executing Liquid from Database Items
    • GraphQL
      • â„šī¸About GraphQL
      • 📋Tutorials
        • Tutorial 1 - Your First Query
        • Tutorial 2 - Pagination
        • Tutorial 3 - Filtering the Results
        • Tutorial 3 - (Answers)
        • Tutorial 4 - Advanced Filtering
        • Tutorial 4 - (Answers)
        • Tutorial 5 - Using Liquid to run GraphQL queries on your Site
        • Tutorial 6 - Variables
        • Tutorial 6 - (Answers)
        • Tutorial 7 - Sorting
        • Tutorial 8 - Building a Liquid API GET Endpoint Page powered by GraphQL queries
        • Tutorial 9 - Using Mutations to Create New Records
        • Tutorial 10 - Using Mutations to Edit a Record
        • Tutorial 11 - Using Mutations to Delete an Item
        • Tutorial 12 - Related Records and Datasources
    • Configuration
      • â„šī¸Field Types
      • â„šī¸Custom Field IDs
    • Zapier Integration
      • â„šī¸Formatting arrays correctly
    • Developer Marketplace
      • â„šī¸About Building Modules
      • â„šī¸Module Setup
      • â„šī¸Site Template Modules - and How to Make Your Own
      • â„šī¸Create Folder Structure
      • â„šī¸Updating Modules
      • â„šī¸Submit Module for Approval
      • â„šī¸Adding Payment to a Module
      • â„šī¸Theme Module Example
      • â„šī¸Data & UI Module Example
      • đŸ’ģReference
      • đŸŒŗFile Structure
    • Release Notes
      • đŸ›ŗī¸Siteglide Admin/API - Changelog
      • đŸ›ŗī¸Module - System Files - Changelog
      • đŸ›ŗī¸Module - eCommerce - Changelog
      • đŸ›ŗī¸Module - Menu - Changelog
      • đŸ›ŗī¸Module - Slider - Changelog
      • đŸ›ŗī¸Module - Secure Zones - Changelog
      • đŸ›ŗī¸Module - FAQ - Changelog
      • đŸ›ŗī¸Module - Events - Changelog
      • đŸ›ŗī¸Module - Blog - Changelog
  • SiteBuilder
    • Build Sites Faster
      • 🚀Quickstart: SiteBuilder
      • About
      • Site Setup
        • đŸ—ī¸Marketplace Themes & Templates
        • đŸ—ī¸Create Site From Template
        • đŸ—ī¸Install SiteBuilder Module
        • đŸ—ī¸Create a Page Template
        • đŸ—ī¸Set Up Tailwind CSS with the recommended CLI method
      • Styling
        • đŸ—ī¸Editing Tailwind CSS using the recommended CLI method
        • đŸ—ī¸Tailwind CSS Themes - Choosing a Build Method
        • đŸ—ī¸Tailwind CSS - Preview Mode
        • đŸ—ī¸Tailwind's JIT Compiler Via CDN (deprecated)
        • đŸ—ī¸Theme Presets
        • đŸ—ī¸Example Tailwind Project Setup
      • Layouts
        • đŸ—ī¸Insert Static Layouts
        • đŸ—ī¸Installing Dynamic Layouts
        • đŸ—ī¸Editing Dynamic Layouts
        • About Layouts
          • đŸ—ī¸Dynamic Layouts
          • đŸ—ī¸Static and Dynamic Form Layouts
          • đŸ—ī¸Sliders
      • đŸ’ģReference
    • Advanced Features
      • 🧞SiteBuilder Live Updates API
        • 👀Live Updates Reference
        • 🔹Live Updates Markup Example
        • 📋Steps to Setting Up Live Updates API in a Module/WebApp Layout
        • 🔹Live Updates Example - Enforcing Filters
        • 📋Steps to Use Live Updates Methods
        • 📋Steps to Initialise Live Updates with JS
        • đŸ—“ī¸Live Updates Changelog
      • â„šī¸SiteBuilder JavaScript
        • â„šī¸Forms JS
        • â„šī¸Social Sharing JS
        • â„šī¸Sliders JS
        • â„šī¸Dark Mode JS
        • â„šī¸Cookie Settings JS
      • â„šī¸SiteBuilder Liquid Includes
        • â„šī¸Pagination
      • â„šī¸SiteBuilder Liquid Functions
        • â„šī¸Detail Page Valid
        • â„šī¸Field Mapping
        • â„šī¸Get Table Config
        • â„šī¸Case From Order ID
      • đŸ—“ī¸SiteBuilder Changelog
    • Extend SiteBuilder
      • â„šī¸Create SiteBuilder Themes
      • â„šī¸Create Marketplace Modules
      • â„šī¸Adding Dynamic Layouts to Themes & Modules
      • â„šī¸Adding Static Layouts to your Theme
      • đŸ’ģReference
  • CMS
    • Dashboard
    • Pages
      • 🚀Quickstart: Pages
      • â„šī¸Studio
      • â„šī¸Code View & Toolbox
      • â„šī¸About Pages
        • â„šī¸Page Settings
        • â„šī¸Custom Fields in Pages
        • â„šī¸Pages with Siteglide CLI
      • â„šī¸About Page Templates
        • â„šī¸Page Templates with Siteglide CLI
        • Preventing Duplicate Content
      • â„šī¸System Pages
      • đŸ’ģReference
      • đŸŒŗFile Structure
    • Content Sections
    • File Manager
      • 🔹About Assets
      • 🔹Linking to Assets Explained
      • 🔧Assets Troubleshooting
      • 🔹Siteglide Scripts Explained
      • đŸ’ģAssets with CLI
      • đŸ”ŧMigrating Assets
      • 📋Steps to Optimise Images on the Fly with Cloudinary
      • 🔹siteglide_head_scripts and siteglide_footer_scripts Explained
      • đŸŒŗAssets File Structure
      • 👀Tags for Assets
    • Forms
      • Quickstart: Forms
      • â„šī¸About Forms
      • 📋Guides: Forms
        • 📋Steps to Using Separate Fields for First Name and Surname in a Form
        • 📋Steps to Programmatically Redirecting after a Form Submission
        • 📋Steps to Adding Form Confirmation Pages
        • 📋Steps to Adding a Progress Bar
        • 📋Steps to Changing Form Styling on Submission Using CSS
        • 📋Steps to Using Custom Field Set fields in a Form's Custom Layout
      • đŸ§™â€â™‚ī¸Go Further: Forms
        • â„šī¸Migrating Forms
        • â„šī¸Explained - Preventing Spam Form Submissions and Captchas
        • â„šī¸Explained - Show Clearly When a User is Already Logged in When Submitting a Form
        • â„šī¸Forms Error Callback and Validation
        • â„šī¸Forms Success Callback
        • â„šī¸File Upload Previews
      • đŸŒŗForms File Structure
      • đŸ’ģReference
      • ❔Troubleshooting
    • Automations
      • 🚀Quickstart: Automations
      • â„šī¸About
        • â„šī¸Email Templates
        • â„šī¸Email Automations and Email Templates with Siteglide CLI
      • 📋Guides
        • â„šī¸Integration Automations
        • â„šī¸A Transactional Email Example
        • â„šī¸An API Call Action Example
        • â„šī¸A Custom Liquid Action Example
        • 📋Steps to Testing Emails on a Staging Site
        • 📋Steps to Authenticating Sendgrid Emails on Live Sites
      • đŸ§™â€â™‚ī¸Go Further
      • đŸ’ģReference
      • đŸŒŗFile Structure
    • Categories
      • 🚀Quickstart: Categories
      • â„šī¸About
        • â„šī¸Outputting Categories on WebApp / Module / eCommerce Layouts
        • â„šī¸Filtering WebApps and Modules by Categories Using Liquid Parameters
      • đŸŒŗFile Structure
      • đŸ’ģReference
    • Company Information
      • â„šī¸About
      • đŸ’ģReference
      • ❔Troubleshooting
    • URL Redirects
  • Modules
    • Core Modules
      • MenuBuilder
        • 🚀Quickstart: Menu Builder
        • â„šī¸About
      • Secure Zones
        • 🚀Quickstart: Secure Zones
        • â„šī¸About
          • 📋Dynamically Assign a Secure Zone during Form Submission
        • đŸ§™â€â™‚ī¸Go Further
          • â„šī¸Secure Zones with Siteglide CLI
          • â„šī¸Using the context.current_user object
      • Media Downloads
        • 🚀Quickstart: Media Downloads
        • â„šī¸Layouts
        • đŸ’ģReference
      • Blog & Authors
        • 🚀Quickstart: Blog & Authors
        • 🔹Blog Archive & Date Filtering
        • 🔹Blog Search
        • 🔹Blog Filter by Category
        • 🔹Blog Filter by Author
        • đŸŒŗFile Structure
        • đŸ’ģReference
      • Events
        • 🚀Quickstart: Events
        • â„šī¸Standard List View
        • â„šī¸Getting Started with Event Filtering & Searching
        • â„šī¸Filter by Category
        • â„šī¸Filter By Host (Author)
        • â„šī¸Filter by Event Dates
        • â„šī¸Datasourcing the Event Host
        • â„šī¸Search
        • â„šī¸Map List View
        • â„šī¸Calendar List View
      • FAQ
        • 🚀Quickstart: FAQ
        • đŸ’ģReference
      • Testimonials
        • 🚀Quickstart: Testimonials
        • đŸ’ģReference
      • Slider
        • 🚀Quickstart: Slider
        • đŸ’ģReference: Slider
    • Community Modules
      • đŸ—ī¸SiteBuilder
      • 🚀CRM Sync
        • â„šī¸About CRM Sync Module
        • 📋Steps to Set Up CRM Sync on an Automation
        • đŸ—“ī¸CRM Sync Changelog
    • Go Further: Modules
      • â„šī¸Front-end Submit Modules
  • WebApps
    • 🚀Quickstart: WebApps
    • WebApp Items
      • 📋Create WebApp Items
      • 📋Importing and Exporting
    • Layouts
      • â„šī¸WebApp List Layout
      • â„šī¸WebApp Detail Layouts
    • Go Further: WebApps
      • 📋Searching by Location
      • 📋Searching - Advanced Filtering
      • 📋Searching - By Keyword
      • 📋Front End Create Forms
      • 📋Front End Update Forms
      • 📋Front End Delete
  • WebApp Troubleshooting
  • eCommerce
    • 🚀Quickstart: eCommerce
    • Get Started
      • 💡About the eCommerce Module
      • Settings
      • 📂Cart, Checkout and Quotes
        • 💡About Cart, Checkout and Quotes
        • 📋Steps to Implement a Guest Checkout Flow
        • 📂Product Views
          • 🔹Product Layouts
          • 🔹Product List Layout
          • 🔹Product Detail Layout
          • 🔹Add to Cart Button
          • 📋Steps to Datasource and Display Related Products
          • 🔹Dynamic Product Layouts based on Categories
          • 📂Attribute Selection
            • 🔹Attribute Layout - Presenting the Choice to the Customer
            • 🔹Attributes - Changing Product Price after Change
          • 📂Discount Selection
            • Discount Codes Layout
            • Minimum Payments
          • 📂Shipping Selection
            • Shipping Options Layout
        • Managing Products
          • Creating and Editing
          • Securing Products
          • Location
          • Custom Fields
          • Edit Module Structure
          • Product Custom Field Sets
          • Inventory
          • Managing Attributes
          • Pricing
          • Product Categories
          • Open Graph Fields
          • SEO Fields
          • Standard Fields
          • Product Import and Export
          • Discounts
        • 📂Cart
          • 🔹Cart Layouts
          • Checking Inventory in Cart
          • Updating Quantity in Cart
          • Updating Displayed Cart Quantity
        • 📋How to Set Up a Shopping Cart and Guest Checkout - Tutorial
        • 📂Checkout Forms
          • 🔹Checkout Form Layouts
          • 🔹Checkout Forms with PayPal
        • 📂Orders
          • Order Confirmation
          • Re-Ordering
          • 🔹Orders Layouts
        • 📋Steps to Add Secure Zones and User Orders View to your Checkout Flow
        • Quotes
        • Selling Digital Products
        • 🔹Volume Pricing
        • 📋Steps - Alternatives to Product Grouping
      • 📂Basic Payment Forms
        • 💡About Basic Payment Forms
        • 📋Steps to Set up a Basic Payment Form (with a Fixed Payment Amount)
        • 📋Authorize.net Basic Payment Forms
        • 📋PayPal Basic Payment Forms
        • 📋Steps to Allow User to Decide Amount they Will Pay
        • 📋Step-by-step Basic Payment Confirmations
        • 👀Basic Payment Forms Reference
        • â„šī¸ecommerce/basic_payment
      • 📂Payment Gateways
        • đŸ’ģBuilding a Custom Payment Gateway
          • 📋Steps to Support Basic Payment Forms with your Custom Payment Gateway
          • 📋Steps to Support Checkout with your Custom Payment Gateway
        • 🔹Paypal Custom Parameters
        • 🔹Styling Stripe Card Elements
        • 💡About Payment Gateways
        • 📋Steps to Switching Payment Gateway
        • 🔹Test Cards
      • 📂Currency and Tax
        • 💡About Tax Codes
        • Currency Changer
        • Tax Code Changer
        • Formatting Currency
      • 📂Subscriptions
        • 💡About Subscriptions
        • Managing Subscriptions
          • Creating Subscription Products
          • Changing Price and Billing Interval
          • Creating a Form for Signing Up and Changing Payment Details
          • Subscription Order Status Explained
          • Terms and Conditions (Good Practice)
        • 📋Subscriptions Payment Gateway Setup
        • Subscriptions List Layout
        • Subscriptions Detail Layout
        • User's Active Subscriptions
        • Subscription Action Required
        • Cancelling Subscriptions
      • đŸŒŗBasic Payment Forms Folder Structure
      • đŸŒŗCart and Checkout Folder Structure
  • CRM
    • 🚀Quickstart: CRM
    • Users
      • User Details
      • User Secure Zones
      • How Users Edit their Email and Password Front End
      • Custom Field Sets & CRM Custom Fields
      • Storing User's Favourite WebApp / Module Items
    • Companies
    • Cases
      • User's Form Submissions (Cases)
  • Site Manager
    • Code Editor
    • Templates (Pages & Email)
    • Headers & Footers
    • Code Snippets (Includes)
      • 🔧Includes Troubleshooting
      • 👀constants_json
      • 👀constants
      • đŸŒŗIncludes File Structure
      • đŸ’ģIncludes with Siteglide CLI
      • 🔧Tags for Includes
    • System Pages
      • Automatic Site Maps
    • System Emails
    • Data Management
    • Admin Menu Editor
    • Integrations
  • Reporting
    • 🚀Quickstart: Reports
  • Miscellaneous
    • System Features
      • Pagination on Liquid Tags
      • Custom Pagination Layouts
      • Timezones in the Siteglide Admin and on the front-end of your Site
      • Module/WebApp Caching
      • Getting Started with Liquid Caching - to Reduce Server Response time and Improve Performance
      • Translating Dates
      • Site Search
      • About Site Search
      • AI Tools for the Rich Text Editor
      • Cookies on Siteglide Sites
    • Front-End Performance
      • Video Embeds
      • Forms Above the Fold
Powered by GitBook
On this page
  • Introduction
  • Glossary
  • Steps for Building your First Liquid Endpoint Page powered by GraphQL
  • Step 1) Create a Page to serve as an Endpoint
  • Step 2) Use CLI to apply advanced settings to the Liquid Page
  • Step 3) Add a GraphQL query with variables
  • Step 4) Add Liquid logic to handle incoming URL parameters
  • Step 5) Use Liquid to feed variables into the Query (and make sure they are the correct type)
  • Step 6) Output results on the Endpoint Page - These will be the response body
  • Step 7) Test the endpoint Page
  • Step 8) Optional - Security and Authorisation
  • Authorization Policy tips
  • Step 9) Optional - Get the Data and use it
  • A Footnote
  • Related Articles

Was this helpful?

Export as PDF
  1. Developer Tools
  2. GraphQL
  3. Tutorials

Tutorial 8 - Building a Liquid API GET Endpoint Page powered by GraphQL queries

PreviousTutorial 7 - SortingNextTutorial 9 - Using Mutations to Create New Records

Last updated 4 months ago

Was this helpful?

This article shows a different use-case for the skills you've already learned- using a GET request to run a query.

Introduction

So far, we've written GraphQL queries which run on Page Load. This is powerful, but wouldn't it be even more useful if you could fetch data after Page load when a User interacts with a Site- e.g. changing page on a list without refreshing the Page? Using XHR (sometimes called Ajax) requests, you can run GraphQL at any time.

This approach can take a little bit of time to set up, but can allow you to create much faster interactive experiences for your Users and opens up a huge range of possible solutions you can build.

We cannot document every way in which you can build this kind of Page, but we will show you the basics and let your imagination do the rest! If you need additional support on this topic beyond the scope of what is documented here, we recommend you speak to one of our or browse the resources we link to at the end of the Article.

Glossary

  • An API - (Application Program Interface) is a form of communication between two services on the internet. Communication takes place between 2 or more endpoints.

  • An endpoint in its simplest form is a URL which allows an API access to a server or application. On Siteglide, we provide you with API endpoints we've built with our , but now you've learned GraphQL, you also have the ability to build your own endpoints when you need them.

  • A method defines the role of the API + Endpoint e.g. a GET method is for "getting" or "fetching" data.

  • JSON (JavaScript Object Notation) is a common file format for exchanging data which is efficient and human-readable. We'll use it in some of our examples. (It's also the default format in which GraphQL results are outputted on the Page.)

Steps for Building your First Liquid Endpoint Page powered by GraphQL

Step 1) Create a Page to serve as an Endpoint

The first step is to create a Page on the Siteglide Admin which will become your API endpoint.

The slug you choose will be the URL via which you'll eventually access the data. It's worth naming the Page and writing a slug which reflect the fact that this Page is not a public-facing Page and should not be editable by Clients. e.g. /api/webapp_1

Step 2) Use CLI to apply advanced settings to the Liquid Page

Using the Siteglide-CLI, pull down your Site's files to your machine and open them up in a Code Editor of your choice. Set up Siteglide-CLI sync so that changes you make will be pushed to the Site.

Open up the Page you've created in a Code Editor of your choice.

We'll be editing the yaml configuration at the top of the page. In my example, you can see the yaml settings between the triple dashes --- It's important when configuring yaml to use exactly 2 spaces instead of tabs for indenting. Your siteglide-cli sync command will alert you to any validation errors.

---
layout: templates/blank_page
max_deep_level: 2
metadata:
  name: API WebApp 1 GET endpoint
  enabled: true
  file_type: page
  last_edit: 1597241196376
redirect_to: ''
redirect_url: ''
---

2) a) Method

So far we've only learned to write GraphQL queries, so your endpoint will be handling GET requests. Set the method property of your page to get:

method: get

2) b) Format

Optionally, you can choose to change the format of your Page. If you like, instead of HTML, you can make your Page a different format, like JSON.

format: json

Note that if you set your Page to a different format now, you'll need to append the URL with the extension later. e.g. a Page with the slug my-slug and format JSON can be accessed at the URL /my-slug.json.

2) c) Remove the Page Template

As your endpoint Page will not be accessed by either humans or search-engine bots, it's much better to remove the Page Template, allowing you to only return the data you need.

layout: ""

2 d) Remove HTML

Unless you're using the HTML format from 2) b), you will need to remove any   tags automatically added to the Page.

2) e) Remove from search engine results

Unlike the other steps, this is not a yaml property on the Page. However, it's included here as a quick sensible step you can take.

You may wish to specify in your robots.txt file that pages with this URL should be ignored by search engines.

2) f) Check yaml

My example looks like this:

---
layout: ""
max_deep_level: 2
metadata:
  name: API WebApp 1 GET endpoint
  enabled: true
  file_type: page
  last_edit: 1597241196376
redirect_to: ''
redirect_url: ''
method: get
format: json
---

Step 3) Add a GraphQL query with variables

In this example, I'll use the following query to fetch data from webapp_1 and change page with the page variable:

query fetch_webapp_1_by_page($page: Int!, $per_page: Int!) {
  records(
    filter: {
      table: { value: "webapp_1" }
    }
    page: $page
    per_page: $per_page
  ) {
    results {
      id
      properties
    }
  }
} 

I'll use the following Liquid to run this query when the endpoint Page is accessed:

{%- graphql fetch_webapp_1_by_page = "fetch_webapp_1_by_page" -%}

Note- I'll be using - before and after my closing Liquid tags to remove unnecessary whitespace from the results- this is optional.

Step 4) Add Liquid logic to handle incoming URL parameters

In the example, we'll pass inputs into the endpoint Page using query parameters on the end of the URL, for example, I already have the URL for accessing the endpoint Page: /api/webapp-1.json

Remember

The ".json" extension should be replaced with the "format" you chose in step 2.

I'll be storing the page I want to request from the endpoint in query parameters like so: /api/webapp-1.json?page=2&per_page=1

You can now use context.params`to read the URL on the endpoint Page and dynamically access each query parameter. I'll store each in a variable before I feed these into the query, in case there is any type coercion to carry out first.

{%- assign page = context.params.page -%}
{%- assign per_page = context.params.per_page -%}

Step 5) Use Liquid to feed variables into the Query (and make sure they are the correct type)

{%- assign page = context.params.page | add: 0 -%}
{%- assign per_page = context.params.per_page | add: 0 -%}

We can then add them to the query.

{%- graphql fetch_webapp_1_by_page = "fetch_webapp_1_by_page",
  page: page,
  per_page: per_page
-%}

If the query expects variables to be Strings you can actually add them straight to the query without assigning as variables first:

{%- graphql fetch_webapp_1_by_page = "fetch_webapp_1_by_page",
  page: context.params.page,
  per_page: context.params.per_page
-%}

Step 6) Output results on the Endpoint Page - These will be the response body

Results are accessible via the variable name you defined in the graphql tag, but at this point we can decide on the format in which we'll display them.

Option 6) a) HTML format

If you decided in step 2 that you didn't want to change the Page format, you should now build the required HTML structure you'd like to send back (this would probably be inserted as it is into a Page via JavaScript).

{%- graphql fetch_webapp_1_by_page = "fetch_webapp_1_by_page",
  page: context.params.page,
  per_page: context.params.per_page
-%}
<div class="row">
  {%- for item in fetch_webapp_1_by_page.records.results -%}
    <div class="col">
      <h2>{{item.properties.name}}</h2>
    </div>
  {%- endfor -%}
</div>

Option 6) b) JSON format

If you decided in step 2 to change the format of the Page, you'll need to use Liquid to output the content in this format.

As GraphQL already outputs in JSON format, this is easy:

{%- graphql fetch_webapp_1_by_page = "fetch_webapp_1_by_page",
  page: context.params.page,
  per_page: context.params.per_page
-%}
{{fetch_webapp_1_by_page}}

Option 6) c) CSV format

For something like CSV, you'll need to use logic to output the data in the correct format -this is just an example and you may need to alter it for your use-case.

We use {% rather than {%- in this example, because we want to preserve new lines to make sure each row of the CSV displays correctly.

{%- graphql fetch_webapp_1_by_page = "fetch_webapp_1_by_page",
  page: page,
  per_page: per_page
-%}
Name,ID,Description
{% for item in fetch_webapp_1_by_page.records.results %}{{item.properties.name}},{{item.id}},
  {{item.properties.webapp_field_1_1}}
{% endfor %}

Step 7) Test the endpoint Page

In your browser, visit the endpoint Page URL and see if the data displays as expected. Test changing the query parameters to see it change the returned data.

A successful JSON endpoint will return valid JSON in the body, as in the example here (other formats should also be checked for valid formats).

{
  "records":{
    "results":[
      {
        "id":"220",
        "properties": {
          "name":"We know guitar music"
          "slug":"we-know-guitar-music"
          "enabled":true
          "og_desc":null
          "og_type":null
          "og_title":null
          "meta_desc":null
          "weighting":null
          "meta_title":null
          "expiry_date":2145916800
          "release_date":1570797009
          "twitter_type":null
          "category_array":[]
          "webapp_field_1_1":"images/about/about-5.jpg"
          "webapp_field_1_2":"Man playing guitar"
          "webapp_field_1_3":"We know guitar music"
          "webapp_field_1_4":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
        }
      }
    ]
  }
}

Changing the URL parameters should allow you to return different responses

Common issues:

  • Your URL should include the relevant file extension e.g. .json for json format, .csv for CSV format. If you are using HTML format, no extension is needed. Below is an example of a 404 response from using the incorrect extension:

  • Your URL should contain any query parameters you need for your query. E.g. in my example, page and per_page are mandatory. Below is an invalid response body resulting from missing URL parameters:

Congratulations! You've built a working GET endpoint using GraphQL and Liquid!

The last two optional steps will expand upon your options for securing the Endpoint and using the data available.

Step 8) Optional - Security and Authorisation

Is your data sensitive and you want only logged in Users to access it? Is your data public and it doesn't need an additional authorisation step?

This step shows you some different ways to make sure your data is secure, but you can skip it if your data is not sensitive or private.

Option 8) a) Using Secure Zones

Adding a Secure Zone to your endpoint Page is a simple way to protect it from Users and bots who should not be accessing it.

A failed access will still generate a successful 2xx response code, because it will succeed in returning HTML body (the 404 message that displays to Users). This is only a problem if you're not using HTML format for your endpoint as it will cause any JavaScript which relies on parsing JSON to fail like so:

In step 9, you'll need to find a way to adapt your JavaScript logic to handle this kind of error which does not rely on the response code, but instead checks the response for the HTML tag <h1>401 - Unauthorised</h1>. See step 9) a) i) and 9) a) ii) for examples of this logic.

Option 8) b) Using Authorization Policies

You can use Siteglide-CLI and platformOS to build an authorization policy that checks the request either comes from a trusted Site or from a trusted User. The benefit of this is that it allows you to return HTTP response codes.

Authorization Policy tips

These tips are intended as inspiration and do not constitute complete examples. They do not require sending a query parameter over in your URL, making them easier to keep secure.

  • If the User has been logged in (to any Secure Zone), you can check this on the Endpoint Page Authorization policy.

{%- if context.current_user.id -%}
  true
{%- endif -%}
  • To check that the request comes from an authorized Page/ Site, you can check this with context:

{%- if context.headers.HTTP_REFERER contains "expected-URL" -%}
  true
{%- endif -%}

Step 9) Optional - Get the Data and use it

On any of your other Pages, you can now send requests to your new endpoint and fetch data. For this you could use JavaScript.

The JavaScript examples provided here are intended for inspiration only. Unfortunately, we cannot advise you on how to adapt these to suit individual projects. See the links at the bottom of this Article for more resources you can use to help plan and develop projects of this kind.

Example 9) a) i) Logging Json Responses

This basic example will request data from the example earlier and console log the response.

The if statement logic checks if a 2xx response code is received (meaning any authorization policies have passed) and that there is no HTML tag containing a 401 code from a Secure Zone check failure. See Step 8) for more details.

  var xReq = new XMLHttpRequest();
  xReq.onload = function () {
    const checkForSecureZone = /401 - Unauthorised/g;
    if (xReq.status >= 200 && xReq.status < 300 && xReq.response.search(checkForSecureZone) == -1 ) {   
      console.log(JSON.parse(xReq.responseText));
    } else {
      console.log('error', xReq.responseText);
    }
  };
  xReq.open('GET', '/api/webapp-1.json?page=1&per_page=1');
  xReq.send();

Example 9) a) ii) Parsing JSON and manipulating the DOM

In this expanded example, we'll fetch the data and then append it to the HTML DOM.

Add HTML and JavaScript

  • An event listener targets the Form and watches for a click event

  • When the Form is submitted, the event triggers the function "getWebappOne".

  • The if statement logic checks if a 2xx response code is received (meaning any authorization policies have passed) and that there is no HTML tag containing a 401 code from a Secure Zone check failure. See Step 8) for more details.

  • The function requests the data from our new endpoint.

  • It then loops over the Items and appends each WebApp Name to the HTML DOM.

HTML

<section class="form form-01">
  <div class="container">
    <form>
      <h2>Get WebApp Names</h2>
      <div class="input-group">
        <label for="page">Page</label>
        <input id="page" type="number" step="1">
      </div>
      <div class="input-group">
        <label for="per_page">Per Page</label>
        <input id="per_page" type="number" step="1">
      </div>
      <button id="submit" class="btn btn-primary">Get WebApp 1</button>
    </form>
  </div>
</section>
<section class="form form-01">
  <div class="container">
    <h2>List of WebApps</h2>
    <div class="row" id="output"></div>
  </div>
</section>

JavaScript

var page = document.querySelector('#page');
var per_page = document.querySelector("#per_page");
var submit = document.querySelector("#submit");
var output = document.querySelector("#output");

function getWebappOne() {
  event.preventDefault();
  var xReq = new XMLHttpRequest();
  xReq.onload = function () {
    const checkForSecureZone = /401 - Unauthorised/g;
    if (xReq.status >= 200 && xReq.status < 300 && xReq.response.search(checkForSecureZone) == -1 ) {
      output.innerHTML = "";
      var jsonParsed = JSON.parse(xReq.response).models.results;
      for(i=0;i<jsonParsed.length;i++) {
        console.log(jsonParsed[i].properties.name)
        output.insertAdjacentHTML('beforeend', '<div class="col">'+jsonParsed[i].properties.name+'</div>');
      }
    } else {
      console.log('error', xReq.responseText);
    }
  }
  xReq.open('GET', '/api/webapp-1.json?page='+page.value+'&per_page='+per_page.value);
  xReq.send();
};
submit.addEventListener('click', getWebappOne);

Example 9) b) Requesting Data From an HTML Page

In the previous two examples, we've used an endpoint with a JSON format endpoint.

You may find it easier to build HTML on the endpoint and when it arrives in the destination Page, output it as it is.

Build HTML on the Endpoint Page

{%- graphql fetch_webapp_1_by_page = "fetch_webapp_1_by_page",
  page: page,
  per_page: per_page
-%}
<div class="row"> 
  {% for this in fetch_webapp_1_by_page.records.results %}
    <div class="col-4">
      <h3>{{this.properties.name}}</h3>
    </div>
  {% endfor %}
</div>

Fetch HTML on the Front End Page

<div class="webapp_1">
</div>

<script>
  var xReq = new XMLHttpRequest();
  xReq.onload = function () {
    if (xReq.status >= 200 && xReq.status < 300) {
      document.querySelector(".webapp_1").innerHTML = "";
      document.querySelector(".webapp_1").insertAdjacentHTML('beforeend', xReq.responseText);
    } else {
      console.log(xReq.responseText);
    }
  };
  xReq.open('GET', '/api/webapp-1?page=1&per_page=1');
  xReq.send();
</script>

A Footnote

Your Liquid endpoint Page will be acting as an extra Layer between your request and platformOS' own GraphQL endpoint. This extra layer is important because it allows you to run your own logic and security checks, before pOS deliver the data.

Related Articles

In this step, we'll be changing the settings of the Page in CLI, as there are available settings here that are not yet editable from Admin. You can learn more about pages in platformOS here: and more about the .

Add a query of your choice using the Liquid graphql tag from and variables from

Accessing these values via the above method tends to set them as String values in the variable. For this example we'll need to change the type to integer- as that's what the query expects. You can refresh your knowledge on changing the type of variable in Liquid in

As this is custom platformOS code, it won't be covered by our support. Learn more about authorization policies on the platformOS docs:

Consider using Live Updates The SiteBuilder Live Updates API, released since this doc was first written might be a quicker alternative here. You can put your GraphQL code in a Code Snippet and follow the docs to .

SiteGurus have created the Live Updates API as part of the SiteBuilder module- designed as an incredibly flexible API endpoint for refreshing almost any Siteglide Layout with different filters- this may save you time implementing your own API endpoint:

The explains how you can get support with planning projects and writing custom code.

MDN have comprehensive documentation on the XML HTTP Request and how to use it in your Front End JavaScript Code: You can also use the modern as an alternative.

Those developers who prefer to use jQuery when writing JavaScript can read more about Ajax Requests here:

platformOS's documentation on Pages includes lots of information about setting up Pages using the yaml configuration:

📋
Experts
public API
https://documentation.platformos.com/developer-guide/pages/pages#content
Siteglide-CLI here
tutorial 5
tutorial 6.
tutorial 6.
https://documentation.platformos.com/developer-guide/authorization-policy/authorization-policy
Live Update a Code Snippet
Live Updates
Siteglide Support Policy
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
https://api.jquery.com/jquery.ajax/
https://documentation.platformos.com/developer-guide/pages/pages