How to make internal requests between two applications of a project

Goal

This guide shows how make an internal request to a different application in the same project. The goal is to display a message sent by a backend API on our frontend.

Assumptions

To complete this, you will need:

Steps

In order to implement this, setup two different applications in your project: frontend and backend. Please refer to the multi-app documentation.

PHP will be used for both applications.

The steps below will create the following project structure:

multiapp/
    .platform/
        routes.yaml
        services.yaml
    backend/
        .platform.app.yaml
        index.php
    frontend/
        .platform.app.yaml
        index.php

1. Setup the base project

Create an empty directory, initialize git and add the Platform.sh remote:

mkdir multiapp
cd !$
git init .
platform project:set https://<region>.platform.sh/projects/<project id>

The git remotes should now be:

git remote -v
platform	<project id>@git.<region>.platform.sh:<project id>.git (fetch)
platform	<project id>@git.<region>.platform.sh:<project id>.git (push)

Create the two required Platform.sh configuration files:

touch ./.platform/routes.yaml
touch ./.platform/services.yaml

2. Create the backend application

Create a subfolder (mkdir backend) and add the following files:

./backend/index.php

<?php

header('Content-type: application/json');
echo json_encode([
	'message' => 'I come from the backend'
]);

./backend/.platform.app.yaml

name: backend

type: "php:7.3"
disk: 256

web:
  locations:
    '/':
      root: ''
      passthru: '/index.php'

Edit ./.platform/routes.yaml and add the configuration for the backend application:

"https://backend.{default}/":
  type: upstream
  upstream: "backend:http"

Any request going to https://backend.{default}/ will be dispatched to the backend application.

Commit the changes and deploy on the Platform.sh environment:

git add .
git commit -m "Add backend app"
git push platform master

The backend application can be accessed at: https://backend.master-7rqtwti-<project id>.<region>.platformsh.site/

Verify that the application returns the message:

curl https://backend.master-7rqtwti-<project id>.<region>.platformsh.site/ | json_pp
{
   "message" : "I come from the backend"
}

3. Create the frontend application

Create the frontend folder:

mkdir frontend

Add the configuration file ./frontend/.platform.app.yaml:

name: frontend

type: "php:7.3"
disk: 256

web:
  locations:
    '/':
      root: ''
      passthru: '/index.php'

./frontend/index.php

<h1>I am the frontend application</h1>

Add the following configuration in ./routes.yaml:

"https://{default}/":
  type: upstream
  upstream: "frontend:http"

The configuration will make any incoming request to the default domain sent to our frontend application.

Commit and deploy the applications:

git add .
git commit -m "Add frontend application"
git push platform master

The frontend is now working:

curl https://master-7rqtwti-<project id>.<region>.platformsh.site/ 
<h1>I am the frontend application</h1>

4. Making an internal request

The public route to the backend could be used but using an internal request is way more efficient and secure.

The first step is to add the relationship. Like any other data service, this will be added in ./frontend/.platform.app.yaml

relationships:
  backend: 'backend:http'

The key of the relationship will be the one used in the $PLATFORM_RELATIONSHIPS array. The first parameter is the name of our second application and http is used as the protocol there.

Read more on our relationships system in our documentation.

Commit and deploy the configuration change:

git add .
git commit -m "Add relationship"
git push platform master

Test the relationship by connecting to the frontend application:

platform ssh
Enter a number to choose an app:
  [0] frontend
  [1] backend
 > 0

The relationships are exposed through the $PLATFORM_RELATIONSHIPS environment variable:

web@<environment id>:~$ base64 -d <<< $PLATFORM_RELATIONSHIPS | json_pp
{
   "backend" : [
      {
         "password" : null,
         "cluster" : "hp5wjyxpgl32m-master-7rqtwti",
         "type" : "php:7.2",
         "path" : null,
         "port" : 80,
         "ip" : "169.254.43.25",
         "rel" : "http",
         "username" : null,
         "hostname" : "eccmt3xjhxsfijzhus545wttki.backend.service._.eu-3.platformsh.site",
         "query" : {},
         "service" : "backend",
         "public" : false,
         "scheme" : "http",
         "host" : "backend.internal",
         "fragment" : null
      }
   ]
}

The backend application can be accessed from the frontend using the host value: backend.internal

A curl request confirms it is working:

web@<environment id>:~$ curl http://backend.internal
{"message":"I come from the backend"}

5. Load the message from the frontend

Replace ./frontend/index.php with the following content:

<?php

$backend = null;
$message = "I am the frontend application";
if (getenv('PLATFORM_RELATIONSHIPS')) {
    $relationshipName = 'backend';
    $relationships = json_decode(base64_decode(getenv('PLATFORM_RELATIONSHIPS')), true);
    foreach ($relationships[$relationshipName] as $endpoint) {
       $backend = $endpoint['host'];
       break;
    }
}

if ($backend) {
  $result = file_get_contents('http://'.$backend.'/');
  $response = json_decode($result, true);
  $message = $response['message'];
}

echo '<h1>'.$message.'</h1>';

Our PHP client implements a lot of other features automatically in a project to avoid fetching configuration settings manually.

And redeploy your project:

git add .
git commit -m "Add backend call on frontend"
git push platform master

The message from the backend is now displayed on our frontend application:

curl https://master-7rqtwti-<project id>.<region id>.platformsh.site/
<h1>I come from the backend</h1>

Conclusion

Making internal requests on different applications inside the same project is possible by leveraging the relationships mechanism implemented by Platform.sh.

1 Like