Skip to content

Rest Documentation

In order to communicate with and maintain the Panda gateway, there is a REST API provided.


Gateway entrypoint

gateway/src/main/scala/com/github/pandafolks/panda/gateway/ApiGatewayRouting.scala

All REST calls targeted against provided routes need to go through this endpoint.
Supported methods: GET,POST,PUT,PATCH,DELETE. Everything after gateway keyword will be resolved and dispatched to one of the routes if the match was found. There is no authorization check.

Status codes:
- 404 - if there is either no matching route found or no available participant capable to serve the request at the given time existed
- everything else - comes directly from the participants' responses

gateway/...

Healthcheck endpoint

gateway/src/main/scala/com/github/pandafolks/panda/gateway/ApiGatewayRouting.scala

Returns Panda Gateway instance details.
Response payload example:

{
    "name": "panda",
    "version": "0.1.0-SNAPSHOT",
    "scalaVersion": "2.13.8",
    "sbtVersion": "1.4.9",
    "javaVersion": "15.0.2+7-27"
}

Status codes:
- 200 - instance is working
- 403 - the user does not have access to this resource

[GET] api/v1/healthcheck

Authentication endpoints

User management endpoints.

user/src/main/scala/com/github/pandafolks/panda/user/AuthRouting.scala

The endpoint is used for acquiring authentication tokens that are needed in the Panda maintaining operations like adding new participants or modifying routes.
Request payload example:

{
  "username": "admin",
  "password": "admin"
} 

Response payload example:

a6f32febacfa21aba3b00be666197b3d8d3157ff-1665825498141-c6d6680e-0a02-44ce-b58e-ffd22e3b31d5

How to use a Token as a Header:
Authorization: "Bearer a6f32febacfa21aba3b00be666197b3d8d3157ff-1665825498141-c6d6680e-0a02-44ce-b58e-ffd22e3b31d5"

Status codes:
- 200 - the user was successfully found
- 401 - the user cannot be recognized

[POST] api/v1/auth/login

The endpoint is used for removing the user with provided credentials.
Request payload example:

{
  "username": "admin",
  "password": "admin"
} 

Status codes:
- 204 - the user was successfully removed
- 401 - the user cannot be recognized

[DELETE] api/v1/auth/destroy

The endpoint is used for creating a new user with provided credentials. The endpoint needs authentication - in other words, there needs to be passed an authentication token of the existing user. This implies that new users can be created only by existing ones.
Request payload example:

{
  "username": "admin",
  "password": "admin"
} 

Status codes:
- 201 - the user was successfully created
- 409 - the user with requested username already exists
- 400 - any error during creation occurred

[POST] api/v1/auth/register

Participants endpoints

Endpoints used for participants (serves the requests are routed to) management. All calls targeting these endpoints are required to be authenticated.

participant/src/main/scala/com/github/pandafolks/panda/participant/ParticipantsRouting.scala

Returns registered groups (unique types of services).
Response payload example:

[
    {
        "name": "cars"
    },
    {
        "name": "planes"
    }
]

Status codes:
- 200 - response successfully returned
- 403 - the user does not have access to this resource
- 404 - there isn't any registered group

[GET] api/v1/groups

Returns all participants (registered services). It is possible to optional filtering out results by the participants' current status.

Response payload example:

[
    {
        "host": "localhost",
        "port": 3000,
        "group": {
            "name": "cars"
        },
        "identifier": "cars-one",
        "healthcheckInfo": {
            "path": "/api/v1/hb"
        },
        "status": {
            "NotWorking": {}
        },
        "health": {
            "Unhealthy": {}
        }
    },
    {
        "host": "localhost",
        "port": 3001,
        "group": {
            "name": "cars"
        },
        "identifier": "cars-two",
        "healthcheckInfo": {
            "path": "api/v1/hb"
        },
        "status": {
            "Working": {}
        },
        "health": {
            "Unhealthy": {}
        }
    },
    {
        "host": "localhost",
        "port": 4000,
        "group": {
            "name": "planes"
        },
        "identifier": "planes-one",
        "healthcheckInfo": {
            "path": "healthcheck"
        },
        "status": {
            "Working": {}
        },
        "health": {
            "Healthy": {}
        }
    }
]

Status codes:
- 200 - response successfully returned
- 403 - the user does not have access to this resource
- 404 - there aren't any results

[GET] api/v1/participants?filter=[all/working/healthy]

Returns all participants (registered services) belonging to a specified group (unique types of services). It is possible to optional filtering out results by the participants' current status.
Response payload example:

[
    {
        "host": "localhost",
        "port": 3000,
        "group": {
            "name": "cars"
        },
        "identifier": "cars-one",
        "healthcheckInfo": {
            "path": "/api/v1/hb"
        },
        "status": {
            "Working": {}
        },
        "health": {
            "Unhealthy": {}
        }
    },
    {
        "host": "localhost",
        "port": 3001,
        "group": {
            "name": "cars"
        },
        "identifier": "cars-two",
        "healthcheckInfo": {
            "path": "api/v1/hb"
        },
        "status": {
            "Working": {}
        },
        "health": {
            "Unhealthy": {}
        }
    }
]

Path params:
- group_name - name of the group for which participants will be returned

Status codes:
- 200 - response successfully returned
- 403 - the user does not have access to this resource
- 404 - there aren't any results

[GET] api/v1/participants/{group_name}?filter=[all/working/healthy]

Creates new participants. The required fields are host, port, and groupName. The identifier needs to be unique across the whole application.

Request payload example:

[
   {
      "identifier":"cars-three",
      "host":"localhost",
      "port":3000,
      "groupName":"cars",
      "working":true,
      "healthcheckRoute":"/api/v1/hb"
   },
   {
      "identifier":"planes-one",
      "host":"localhost",
      "port":4000,
      "groupName":"planes",
      "working":true
   }
]

Response payload example:

{
    "message": "Created successfully 1 participants out of 2 requested",
    "successfulParticipantIdentifiers": [
        "cars-three"
    ],
    "errors": [
        "[AlreadyExists$]: Participant with identifier \"planes-one\" already exists"
    ]
}

Defaults (auto generated if omitted in the payload):
- identifier - "{host}-{port}-{groupName}"
- working - true
- healthcheckRoute - "/healthcheck"

Status codes:
- 200 - creation request performed
- 403 - the user does not have access to this resource

[POST] api/v1/participants

Updates participants' properties. Participant recognition is made based on the identifier. Only those properties that were contained in the payload will be updated.

Request payload example:

[
   {
      "identifier":"cars-three",
      "host":"localhost",
      "port":3003,
      "groupName":"cars",
      "working":true,
      "healthcheckRoute":"/api/v1/hb"
   },
   {
      "identifier":"planes-two",
      "host":"110.110.110"
   }
]

Response payload example:

{
    "message": "Modified successfully 1 participants out of 2 requested",
    "successfulParticipantIdentifiers": [
        "cars-three"
    ],
    "errors": [
        "[NotExists$]: Participant with identifier \"planes-two\" does not exist"
    ]
}

Defaults (auto generated if omitted in the payload):
- identifier - "{host}-{port}-{groupName}" (if the participant identifier is auto generated, this is impossible to modify none of the host, port, groupName)

Status codes:
- 200 - update request performed
- 403 - the user does not have access to this resource

[PUT] api/v1/participants

Removes participants with delivered identifiers.

Request payload example:

["cars-one", "cars-two", "planes-four"]

Response payload example:

{
    "message": "Removed successfully 2 participants out of 3 requested",
    "successfulParticipantIdentifiers": [
        "cars-one",
        "cars-two"
    ],
    "errors": [
        "[NotExists$]: Participant with identifier \"planes-four\" does not exist"
    ]
}

Status codes:
- 200 - removal request performed
- 403 - the user does not have access to this resource

[DELETE] api/v1/participants

Routes endpoints

Endpoints used for mappers and prefixes management. All calls targeting these endpoints are required to be authenticated.

routes/src/main/scala/com/github/pandafolks/panda/routes/RoutesRouting.scala

Returns the union of all available Mappers and Prefixes. It is possible to optional filtering out results either by the group name the Mappers belong to or by the Mappers' standalone property. If the Mapper is a standalone one that means it can be used directly via the Gateway and in the Composition Mappers, whereas not standalone Mappers can be used only via Composition Mappers.

Response payload example:

{
    "mappers": [
        [
            "cars/all",
            {
                "mapping": "cars",
                "method": "POST",
                "isStandalone": true
            }
        ],
        [
            "cars/supercars/**",
            {
                "mapping": "planes",
                "method": "GET",
                "isStandalone": true
            }
        ],
        [
            "planes/{{plane_id}}/passengers",
            {
                "mapping": "planes",
                "method": "GET",
                "isStandalone": true
            }
        ],
        [
            "planes/somepath1/param123",
            {
                "mapping": "planes",
                "method": "GET",
                "isStandalone": false
            }
        ],
        [
            "cars/all",
            {
                "mapping": "cars",
                "method": "GET",
                "isStandalone": true
            }
        ],
        [
            "planes/somepath1/param123",
            {
                "mapping": "planes",
                "method": "DELETE",
                "isStandalone": true
            }
        ],
        [
            "cars/rent/complex2",
            {
                "mapping": {
                    "property2": {
                        "property3": "planes/somepath1/param123"
                    },
                    "property1": "some/other/path"
                },
                "method": "GET",
                "isStandalone": true
            }
        ]
    ],
    "prefixes": {
        "cars": "api/v1",
        "planes": "api/v2"
    }
}

Status codes:
- 200 - response successfully returned
- 403 - the user does not have access to this resource

[GET] api/v1/routes?group=[{group_name}]&standalone=[true/false]

Returns all available Mappers. It is possible to optional filtering out results by the standalone property. If the Mapper is a standalone one that means it can be used directly via the Gateway and in the Composition Mappers, whereas not standalone Mappers can be used only via Composition Mappers.

Response payload example:

[
    [
        "cars/all",
        {
            "mapping": "cars",
            "method": "POST",
            "isStandalone": true
        }
    ],
    [
        "cars/supercars/**",
        {
            "mapping": "planes",
            "method": "GET",
            "isStandalone": true
        }
    ],
    [
        "planes/{{plane_id}}/passengers",
        {
            "mapping": "planes",
            "method": "GET",
            "isStandalone": true
        }
    ],
    [
        "planes/somepath1/param123",
        {
            "mapping": "planes",
            "method": "GET",
            "isStandalone": false
        }
    ],
    [
        "cars/all",
        {
            "mapping": "cars",
            "method": "GET",
            "isStandalone": true
        }
    ],
    [
        "planes/somepath1/param123",
        {
            "mapping": "planes",
            "method": "DELETE",
            "isStandalone": true
        }
    ],
    [
        "cars/rent/complex2",
        {
            "mapping": {
                "property2": {
                    "property3": "planes/somepath1/param123"
                },
                "property1": "some/other/path"
            },
            "method": "GET",
            "isStandalone": true
        }
    ]
]

Status codes:
- 200 - response successfully returned
- 403 - the user does not have access to this resource

[GET] api/v1/routes/mappers?standalone=[true/false]

Returns all available prefixes.

Response payload example:

{
    "cars": "api/v1",
    "planes": "api/v2"
}

Status codes:
- 200 - response successfully returned
- 403 - the user does not have access to this resource

[GET] api/v1/routes/prefixes

Creates Mappers and Prefixes. Mappers' uniqueness is based on the combination of the Route and the HTTP Method.

Request payload example:

{
   "mappers":[
      [
         "cars/supercars/**",
         {
            "mapping":"planes",
            "method":"GET",
            "isStandalone":true
         }
      ],
      [
         "planes/{{plane_id}}/passengers",
         {
            "mapping":"planes",
            "method":"get",
            "isStandalone":true
         }
      ],
      [
         "/cars/rent/complex2",
         {
            "mapping":{
               "property1":"some/other/path",
               "property2":{
                  "property3":"/planes/somepath1/param123"
               }
            },
            "method":"GET",
            "isStandalone":true
         }
      ],
      [
         "/planes/somepath1/param123",
         {
            "mapping":"planes",
            "method":"DELETE",
            "isStandalone":true
         }
      ],
      [
         "/planes/somepath1/param123",
         {
            "mapping":"planes",
            "method":"GET",
            "isStandalone":false
         }
      ],
      [
         "/cars/all",
         {
            "mapping":"cars"
         }
      ],
      [
         "/cars/all",
         {
            "mapping":"cars",
            "method":"POST"
         }
      ]
   ],
   "prefixes":{
      "cars":"api/v1",
      "planes":"/api/v2"
   }
}

Response payload example:

{
    "message": "Created successfully 7 routes out of 7 requested and 2 prefixes out of 2 requested",
    "successfulRoutes": [
        "cars/rent/complex2",
        "planes/somepath1/param123",
        "planes/somepath1/param123",
        "cars/all",
        "cars/all"
    ],
    "successfulGroupPrefixes": [
        "cars"
    ],
    "routesErrors": [
        "[AlreadyExists$]: Route 'cars/supercars/**' [GET] already exists",
        "[AlreadyExists$]: Route 'planes/{{plane_id}}/passengers' [GET] already exists"
    ],
    "groupPrefixesErrors": [
      "[AlreadyExists$]: Group 'planes' has already defined prefix"
    ]
}

Defaults (auto generated if omitted in the payload):
- isStandalone - true
- method - GET

Status codes:
- 200 - creation request performed
- 403 - the user does not have access to this resource

[POST] api/v1/routes

Updates (and creates if not exists) Mappers and Prefixes. Mappers' uniqueness is based on the combination of the Route and the HTTP Method.

Request payload example:

{
   "mappers":[
      [
         "cars/supercars/**",
         {
            "mapping":"planes",
            "method":"GET",
            "isStandalone":true
         }
      ],
      [
         "planes/{{plane_id}}/passengers",
         {
            "mapping":"planes",
            "method":"get",
            "isStandalone":true
         }
      ],
      [
         "/cars/rent/complex2",
         {
            "mapping":{
               "property1":"some/other/path",
               "property2":{
                  "property3":"/planes/somepath1/param123"
               }
            },
            "method":"GET",
            "isStandalone":true
         }
      ],
      [
         "/planes/somepath1/param123",
         {
            "mapping":"planes",
            "method":"DELETE",
            "isStandalone":true
         }
      ],
      [
         "/planes/somepath1/param123",
         {
            "mapping":"planes",
            "method":"GET",
            "isStandalone":false
         }
      ],
      [
         "/cars/all",
         {
            "mapping":"cars"
         }
      ],
      [
         "/cars/all",
         {
            "mapping":"cars",
            "method":"POST"
         }
      ]
   ],
   "prefixes":{
      "cars":"api/v1",
      "planes":"/api/v2"
   }
}

Response payload example:

{
    "message": "Created successfully 7 routes out of 7 requested and 2 prefixes out of 2 requested",
    "successfulRoutes": [
        "cars/supercars/**",
        "planes/{{plane_id}}/passengers",
        "cars/rent/complex2",
        "planes/somepath1/param123",
        "planes/somepath1/param123",
        "cars/all",
        "cars/all"
    ],
    "successfulGroupPrefixes": [
        "cars",
        "planes"
    ],
    "routesErrors": [],
    "groupPrefixesErrors": []
}

Defaults (auto generated if omitted in the payload):
- isStandalone - true
- method - GET

Status codes:
- 200 - update request performed
- 403 - the user does not have access to this resource

[POST] api/v1/routes/override

Removes Mappers and Prefixes. Mappers' uniqueness is based on the combination of the Route and the HTTP Method.

Request payload example:

{
   "mappers":[
      {
         "route":"/planes/somepath1/param123",
         "method":"DELETE"
      },
      {
         "route":"cars/all/"
      }
   ],
   "prefixes":[
      "planes2",
      "cars23",
      "cars"
   ]
}

Response payload example:

{
    "message": "Removed successfully 2 routes out of 2 requested and 1 prefixes out of 3 requested",
    "successfulRoutes": [
        "planes/somepath1/param123",
        "cars/all"
    ],
    "successfulGroupPrefixes": [
        "cars"
    ],
    "routesErrors": [],
    "groupPrefixesErrors": [
        "[NotExists$]: There is no prefix associated with the group 'planes2'",
        "[NotExists$]: There is no prefix associated with the group 'cars23'"
    ]
}

Defaults (auto generated if omitted in the payload):
- method - GET

Status codes:
- 200 - removal request performed
- 403 - the user does not have access to this resource

[DELETE] api/v1/routes