GithubHelp home page GithubHelp logo

fanette-guilloud-backend's Introduction

Kirby Headless Starter

โ„น๏ธ Send a request with a Authorization: Bearer test header to the live playground for an example response.

This starter kit is intended for an efficient and straight forward headless usage of Kirby. Thus, you will only be able to fetch JSON-encoded data. No visual data shall be presented. You can either use Kirby's default template system to build data (which will be auto-encoded to JSON) or use KQL to fetch data in your consuming application.

Routing and JSON-encoded responses are handled by the internal headless plugin, specifically its global routes and API routes for KQL.

This project works well with nuxt-kql.

Example Projects

Key Features

  • ๐Ÿฆญ Optional bearer token for authentication
  • ๐Ÿ”’ public or private API
  • ๐Ÿงฉ KQL with bearer token support via new /api/kql route
  • โšก๏ธ Cached KQL queries
  • ๐ŸŒ Multilang support for KQL queries
  • ๐Ÿ˜ตโ€๐Ÿ’ซ No CORS issues!
  • ๐Ÿข Build your own API chain
  • ๐Ÿ—‚ Templates present JSON instead of HTML
    • Fetch either /example or /example.json
    • You decide, which data you share
  • ๐Ÿฆพ Express-esque API builder with middleware support

Use Cases

Fetch data from a headless Kirby instance:

  • 1๏ธโƒฃ by using Kirby's default template system
  • 2๏ธโƒฃ by using KQL

Head over to the usage section for instructions.

Prerequisites

  • PHP 8.0+

Kirby is not a free software. You can try it for free on your local machine but in order to run Kirby on a public server you must purchase a valid license.

Setup

Composer

Kirby-related dependencies are managed via Composer and located in the vendor directory. To install them, run:

composer install

Environment Variables

Duplicate the .env.development.example as .env:

cp .env.development.example .env

Optionally, adapt it's values.

โ„น๏ธ Make sure to set the correct requesting origin instead of the wildcard KIRBY_HEADLESS_ALLOW_ORIGIN=* for your deployment.

Usage

Bearer Token

It's recommended to secure your API with a token. To do so, set the environment variable KIRBY_HEADLESS_API_TOKEN with a token string of your choice.

You will then have to provide the HTTP header Authentication: Bearer ${token} with each request.

โš ๏ธ Without a token your page content will be publicly accessible to everyone.

Public API

If the environment variable KIRBY_HEADLESS_API_TOKEN is left empty, the API will be publicly accessible.

โ„น๏ธ The internal /api/kql route will always enforce bearer authentication, unless you explicitly disable it in your config (see below).

Templates

Create templates just like you normally would in any Kirby project. Instead of writing HTML, we build arrays and encode them to JSON. The internal route handler will add the correct content type and also handles caching (if enabled).

๐Ÿ†’ Example template
# /site/templates/about.php

$data = [
  'title' => $page->title()->value(),
  'layout' => $page->layout()->toLayouts()->toArray(),
  'address' => $page->address()->value(),
  'email' => $page->email()->value(),
  'phone' => $page->phone()->value(),
  'social' => $page->social()->toStructure()->toArray()
];

echo \Kirby\Data\Json::encode($data);
๐Ÿ†’ Fetch that data in the frontend
import { $fetch } from "ohmyfetch";

const apiToken = "test";

const response = await $fetch(
  "<website-url>/about.json",
  {
    // Optional, only if you use `KIRBY_HEADLESS_API_TOKEN`
    headers: {
      Authentication: `Bearer ${apiToken}`,
    },
  }
);

console.log(response);

KirbyQL

A new KQL endpoint supporting caching and bearer token authentication is implemented under /api/kql.

Fetch KQL query results like you always do, but provide an Authentication header with your request:

๐Ÿ†’ Fetch example
import { $fetch } from "ohmyfetch";

const apiToken = "test";

const response = await $fetch("<website-url>/api/kql", {
  method: "POST",
  body: {
    query: "page('notes').children",
    select: {
      title: true,
      text: "page.text.toBlocks",
      slug: true,
      date: "page.date.toDate('d.m.Y')",
    },
  },
  headers: {
    Authentication: `Bearer ${apiToken}`,
  },
});

console.log(response);

To disable the bearer token authentication for your Kirby instance and instead use the basic authentication method, set the following in your config.php:

'kql' => [
    'auth' => true
]

โ„น๏ธ The KQL default endpoint /api/query remains using basic authentication and also infers the kql.auth config option.

API Builder

This headless starter includes an Express-esque API builder, defined in the KirbyHeadless\Api\Api class. You can use it to re-use logic like handling a token or verifying some other incoming data.

Take a look at the built-in routes to get an idea how you can use the API builder to chain complex route logic.

It is also useful to consume POST requests including JSON data:

๐Ÿ†’ Example custom route
# /site/config/config.php
return [
    'routes' => [
        [
            'pattern' => 'post-example',
            'method' => 'POST',
            'action' => Api::createHandler(
                [\KirbyHeadless\Api\Middlewares::class, 'hasBearerToken'],
                [\KirbyHeadless\Api\Middlewares::class, 'hasBody'],
                function ($context) {
                    // Get the data of the POST request
                    $data = $context['body'];

                    // Do something with `$data` here

                    return Api::createResponse(201);
                }
            )
        ]
    ]
];

You you use one of the built-in middlewares or write custom ones in by extending the middleware class or creating a custom class defining your custom middleware functions:

๐Ÿ†’ Example custom middleware
/**
 * Check if `foo` is sent with the request
 * and bail with an 401 error if not
 *
 * @param array $context
 * @return mixed
 */
public static function hasFooParam($context)
{
    if (empty(get('foo'))) {
        return Api::createResponse(401);
    }
}

Preview URL to the Frontend

With the headless approach, the default preview link from the Kirby Panel won't make much sense. Thus, we have to overwrite it. With a custom page method provided by this headless kit:

options:
  # Or `site.frontendUrl` for the `site.yml`
  preview: "{{ page.frontendUrl }}"

Set your frontend URL in your .env:

KIRBY_HEADLESS_FRONTEND_URL=https://example.com

If left empty, the preview button will be disabled.

Deployment

โ„น๏ธ See ploi-deploy.sh for exemplary deployment instructions.

โ„น๏ธ Some hosting environments require to uncomment RewriteBase / in .htaccess to make site links work.

FAQ

Why Not Use Content Representations?

Content representations are great. But they require a non-representing template. Otherwise, the content representation template just would not be read by Kirby. This means, you would have to create the following template structure:

  • default.php
  • default.json.php
  • home.php
  • home.json.php
  • โ€ฆ and so on

To simplify this approach, we use the standard template structure, but encode each template's content as JSON via the internal route middleware.

How Can I Redirect Browser Visitors to the Panel?

Content managers or editors visiting the headless Kirby site may not want to see any API response, but use the Panel solely. To let them automatically be redirected to the Panel, set the following option in your Kirby configuration:

# /site/config/config.php
return [
    // Further Kirby headless options
    'headless' => [
        // Redirect to the Panel if no authorization header is sent, useful for
        // content managers visiting the site
        'autoPanelRedirect' => false
    ]
]

A middleware checks if an Authentication header is set, which is not the case in the browser context.

License

MIT License ยฉ 2022 Johann Schopplich

fanette-guilloud-backend's People

Contributors

saschakrischock avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.