Introduction
Lobster pipelines are built from typed steps that pass data forward using a reference syntax. Each step's output becomes available to subsequent steps through explicit references like $step.stdout and $step.json. This lesson covers the piping syntax, step references, and how to write complete workflow definitions.
Key Concepts
- Step References: The
$steps.<id>.<output>syntax for accessing previous step outputs - $step.stdout: The standard text output of a step
- $step.json: The parsed JSON output of a step, enabling structured data passing
- Piping Syntax: How data flows from one step to the next through explicit input declarations
- .lobster Format: The file extension for Lobster workflow definitions (supports JSON and YAML)
Real World Context
A data engineering team builds a pipeline that extracts user analytics from their database, transforms the data into a report format, and loads it into their business intelligence dashboard. Each step produces output that the next step consumes. Using Lobster's reference syntax, they create a clean, readable pipeline where data flow is explicit and verifiable.
Deep Dive
Step Reference Syntax
Every step's output is available to subsequent steps via the $steps namespace:
yamlsteps: - id: fetch-users type: http config: url: "https://api.example.com/users" method: GET - id: count-active type: transform input: $steps.fetch-users.json config: expression: ".users | map(select(.active)) | length"
The second step references $steps.fetch-users.json, which provides the parsed JSON response from the first step. The transform step then applies a jq-like expression to count active users.
stdout vs json References
Steps produce both text and structured output:
yamlsteps: - id: run-tests type: shell config: command: "npm test -- --json" - id: parse-results type: transform input: $steps.run-tests.json config: expression: ".testResults | { passed: .numPassedTests, failed: .numFailedTests }" - id: format-report type: template input: $steps.run-tests.stdout config: template: "Test output:\n{{input}}"
The parse-results step uses .json to work with structured data. The format-report step uses .stdout to include the raw text output in a template. Choose the reference type based on whether you need structured or raw data.
Complete Pipeline Example
A full .lobster workflow file:
yaml# deploy-staging.lobster name: deploy-staging version: 2.1.0 trigger: manual steps: - id: pull-latest type: shell config: command: "git pull origin main" - id: run-tests type: shell config: command: "npm test" dependsOn: pull-latest - id: build type: shell config: command: "npm run build" dependsOn: run-tests - id: deploy type: shell config: command: "kubectl apply -f k8s/staging/" dependsOn: build - id: verify type: http config: url: "https://staging.example.com/health" expectedStatus: 200 dependsOn: deploy
This pipeline pulls the latest code, runs tests, builds the project, deploys to Kubernetes, and verifies the deployment health. Each step explicitly declares its dependency using dependsOn, making the execution order unambiguous.
JSON Format
The same pipeline in JSON:
json{ "name": "deploy-staging", "version": "2.1.0", "trigger": "manual", "steps": [ { "id": "pull-latest", "type": "shell", "config": { "command": "git pull origin main" } }, { "id": "run-tests", "type": "shell", "config": { "command": "npm test" }, "dependsOn": "pull-latest" } ] }
Both JSON and YAML formats are fully supported. Choose whichever your team prefers.
Common Pitfalls
- Referencing a step that has not run yet: Step references are resolved in order. You cannot reference
$steps.deploy.stdoutfrom thebuildstep becausedeployruns afterbuild. - Using .json on non-JSON output: If a step produces plain text, referencing
.jsonwill cause a parse error. Use.stdoutfor text output. - Forgetting dependsOn for parallel steps: Without explicit dependencies, Lobster may attempt to run steps in parallel if they have no data dependencies.
Best Practices
- Use descriptive step IDs that make references self-documenting (e.g.,
$steps.fetch-users.jsonis clearer than$steps.step1.json). - Prefer .json references for structured data to enable downstream transformations and validations.
- Add dependsOn explicitly even when data references already imply the dependency, for clarity.
Summary
- Step references use
$steps.<id>.<output>syntax to pass data between steps .stdoutprovides raw text output;.jsonprovides parsed structured data- Workflow files use the .lobster extension and support both JSON and YAML formats
- The
dependsOnfield explicitly declares execution order between steps - Always use descriptive step IDs to make references self-documenting