Applications

A Application is a published front-end surface over a Backend. Its application.json manifest declares structured needs that the platform resolves against the Backend's endpoint aliases.

TL;DR

  • A Application is a hosted (or locally-iterated) container serving a UI, bound to one or more Backends through a application.json manifest.
  • The manifest's needs list is a set of structured Backend-endpoint requirements: each need names a local handle (name), the Backend endpoint alias it consumes (role), the endpoint kind (ingress or egress), the allowed transports (http / ws / sse / webrtc), and whether the need is required.
  • Endpoint URLs are a Backend property, and a live Deployment is what makes those URLs serve. The Application resolves a need to a concrete URL on the Backend, not on a particular Deployment.
  • Application commands: create / build / register / deploy / update / list / publish / remove. register is the local-only stub for iterating against a Backend without platform hosting.

Mental model — needs ↔ aliases

A application.json need is the consumer half of a binding contract; the other half is a Backend endpoint alias. The endpoint-alias model — how aliases decouple the graph from the surface and map a (vertex, endpoint-name) to a role — is owned by /concepts/solutions; this page covers only how an Application declares needs and resolves them against those aliases.

A need is a structured requirement the Application publishes for the platform to satisfy:

   application.json need
   ┌─────────────────────────────┐
   │ name:       upload          │
   │ role:       upload          │
   │ kind:       ingress         │
   │ transports: [http]          │
   │ required:   true            │
   └─────────────────────────────┘

The platform matches a need to an alias by role, then validates that the alias kind matches and that at least one of the need's listed transports overlaps with what the alias supports. If the alias does not exist, the kind does not match, or no transport overlaps, the resolution fails closed: a required: true need blocks the Application, and a required: false need is dropped.

The Application does not own the Backend graph, the Deployment lifecycle, the Component implementations, the container layout, or the Runtime placement. Those are upstream concerns the Application consumes through resolved endpoint URLs.

Walkthrough — bind a UI to a Backend

Pre-requisites: a Backend with the endpoint aliases the UI needs (declared with ppl backend change-endpoint-alias), and an image (or static directory) for the UI.

# 1. declare the needs in application.json:
#    {
#      "name": "doc_scanner_ui",
#      "needs": [
#        {
#          "name":       "upload",
#          "role":       "upload",
#          "kind":       "ingress",
#          "transports": ["http"],
#          "required":   true
#        },
#        {
#          "name":       "events",
#          "role":       "events",
#          "kind":       "egress",
#          "transports": ["ws", "http"],
#          "required":   true
#        }
#      ]
#    }

# 2. register the Application + its needs against an existing image
ppl application create --manifest ./application.json --image doc_scanner_ui:latest

# 3. start its container
ppl application deploy doc_scanner_ui

When the Backend is live behind a running Deployment, each need resolves to a concrete URL on the Backend's published endpoint. The UI posts uploads to the upload URL and subscribes to the events URL; the Backend's vertex layout, container placement, and Runtime stay invisible to it.

Variations

Build the image from a static directory. ppl application build doc_scanner_ui --dir ./dist packages a static bundle into the Application image and starts a container in one step, for UIs that are plain HTML/CSS/JS.

Register only — local iteration. ppl application register doc_scanner_ui --manifest ./application.json creates an internal-mode Application row without an image or a container. The row is visible only to you; pair it with a local dev server (npm run dev) while iterating on the UI, then promote it later with ppl application build.

Replace the needs list. ppl application update doc_scanner_ui --manifest ./application.json re-uploads the manifest's needs array, replacing the previous set. --image swaps the Docker image, and --new-name renames the Application.

Redeploy an already-running Application. ppl application deploy doc_scanner_ui --force redeploys the container even when one is already running, which applies a preceding update --image.

Promote a prerelease. ppl application publish doc_scanner_ui moves a prerelease Application into the released catalog. This changes visibility, not runtime: no rebuild, no restart.

Reference snapshot — application.json

{
  "name": "doc_scanner_ui",
  "needs": [
    {
      "name":       "<application_local_handle>",
      "role":       "<Backend endpoint alias>",
      "kind":       "ingress" | "egress",
      "transports": ["http" | "ws" | "sse" | "webrtc", ...],
      "required":   true | false
    }
  ]
}
FieldMeaning
nameApplication identifier. Used by every Application-scoped command.
needs[].nameApplication-local handle for the requirement (any short string the UI references).
needs[].roleThe Backend endpoint alias this need binds to. Must match a change-endpoint-alias value on the Backend.
needs[].kindingress (the Application pushes data in) or egress (the Application consumes data out). Must match the Backend endpoint's kind.
needs[].transportsAllowed wire transports for the binding: any subset of http, ws, sse, webrtc. At least one must overlap with what the Backend endpoint supports.
needs[].requiredIf true, an unsatisfied need blocks the Application; if false, the Application comes up without it.

Run it

ppl application create   --manifest ./application.json --image <image:tag>
ppl application build    <name> --dir <static_dir> [--tag <tag>]
ppl application register <name> [--manifest ./application.json]   # internal stub, no container
ppl application deploy   <name> [--force]
ppl application list
ppl application update   <name> [--image <image:tag>] [--manifest <path>] [--new-name <new>]
ppl application publish  <name>
ppl application remove   <name>

Related

  • Solutions — the full stack; the Application is the UI on top of a Backend and its Deployment.
  • Backends — where the endpoint aliases that needs bind to are declared.
  • Deployments — the runtime backing the Backend's published endpoint URLs.

Was this page helpful?