Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
coverage: none

- name: Validate composer.json and composer.lock
run: composer validate --strict

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
Expand All @@ -36,7 +42,7 @@ jobs:
run: vendor/bin/ecs check

- name: Run static analysis via PHPStan
run: vendor/bin/phpstan --xdebug analyse src tests
run: vendor/bin/phpstan analyse src tests

- name: Run test suite
run: composer run-script test
147 changes: 104 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,71 +1,100 @@
# Serverless Workflow Specification - PHP SDK
# Open Workflow Specification - PHP SDK
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fopen-workflow-specification%2Fsdk-php.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fopen-workflow-specification%2Fsdk-php?ref=badge_shield)


Provides the PHP API/SPI for the [Serverless Workflow Specification](https://github.com/serverlessworkflow/specification).
Provides the PHP API/SPI for the [Open Workflow Specification](https://github.com/open-workflow-specification/specification)
(formerly the Serverless Workflow Specification).

With the SDK you can:
* Programmatically build workflow definitions
* Programmatically build workflow definitions
* Parse workflow JSON and YAML definitions
* Validate workflow definitions
* Validate workflow definitions against the DSL schema

### Status

Current SDK version conforms to the [Serverless Workflow specification v0.8](https://github.com/serverlessworkflow/specification/tree/0.8.x).
The current SDK version conforms to the [Open Workflow Specification DSL v1.0.1](https://github.com/open-workflow-specification/specification/tree/v1.0.1).
Every example of the specification is parsed, serialized without loss and validated by the test suite.

Definitions written for the legacy 0.8 DSL are not supported by this version. Use the
[migration tool](https://github.com/open-workflow-specification/migration-tool) to convert them, or the
`1.0.0` release of this package for the legacy object model.

## Installation

```bash
composer install serverlessworkflow/sdk
composer require serverlessworkflow/sdk
```

## Build
PHP 8.2 or later is required.

## Build

Every DSL object is a class with public properties named after the DSL properties. Objects can be built from
arrays, from instances, or from a mix of both; task lists keep the order of their named tasks.

```php
use Serverless\Workflow\Action;
use Serverless\Workflow\ActionDataFilter;
use Serverless\Workflow\FunctionDef;
use Serverless\Workflow\FunctionRef;
use Serverless\Workflow\OperationState;
use Serverless\Workflow\Document;
use Serverless\Workflow\Endpoint;
use Serverless\Workflow\Task\Call\HttpArguments;
use Serverless\Workflow\Task\CallHttp;
use Serverless\Workflow\Task\SetTask;
use Serverless\Workflow\TaskList;
use Serverless\Workflow\Timeout;
use Serverless\Workflow\Workflow;

$workflow = new Workflow([
'id' => 'greeting',
'name' => 'Greeting Workflow',
'description' => 'Greet Someone',
'version' => '1.0',
'specVersion' => '0.8',
'start' => 'Greet',
'states' => [
new OperationState([
'name' => 'Greet',
'type' => 'operation',
'actions' => [
new Action([
'functionRef' => new FunctionRef([
'refName' => 'greetingFunction',
'arguments' => [
'name' => '${ .person.name }',
'document' => new Document([
'dsl' => '1.0.1',
'namespace' => 'examples',
'name' => 'buy-pet',
'version' => '0.1.0',
]),
'do' => new TaskList([
'getPet' => new CallHttp([
'with' => new HttpArguments([
'method' => 'get',
'endpoint' => new Endpoint([
'uri' => 'https://petstore.swagger.io/v2/pet/{petId}',
'authentication' => [
'bearer' => [
'token' => '${ .token }',
],
]),
'actionDataFilter' => new ActionDataFilter([
'results' => '${ .greeting }',
]),
],
]),
]),
]),
'markAsSold' => new SetTask([
'set' => [
'status' => 'sold',
],
'end' => true,
]),
],
'functions' => [
new FunctionDef([
'name' => 'greetingFunction',
'operation' => 'file://myapis/greetingapis.json#greeting',
'buyPet' => new CallHttp([
'with' => [
'method' => 'put',
'endpoint' => 'https://petstore.swagger.io/v2/pet/{petId}',
'body' => '${ . + { status: .status } }',
],
'then' => 'end',
]),
],
]),
'timeout' => new Timeout([
'after' => 'PT5M',
]),
]);
```

Tasks are resolved to their concrete type (`CallHttp`, `CallOpenApi`, `CallGrpc`, `CallAsyncApi`, `CallFunction`,
`DoTask`, `EmitTask`, `ForTask`, `ForkTask`, `ListenTask`, `RaiseTask`, `RunTask`, `SetTask`, `SwitchTask`,
`TryTask`, `WaitTask`) from their properties when they are created from arrays:

```php
use Serverless\Workflow\Task\Task;

$task = Task::fromArray(['wait' => 'PT30S']); // Serverless\Workflow\Task\WaitTask
```

Properties the model does not know are preserved as additional properties, so definitions using extensions or a
newer DSL can still be parsed, serialized and validated.

## Parse

### Convert from JSON/YAML source
Expand All @@ -76,24 +105,56 @@ $workflow = Workflow::fromJson(file_get_contents('workflow.json'));
$workflow = Workflow::fromYaml(file_get_contents('workflow.yaml'));
```

### Navigate

```php
$getPet = $workflow->do->get('getPet'); // Serverless\Workflow\Task\CallHttp
$method = $getPet->with->method; // 'get'
$uri = $getPet->with->endpoint->uri; // 'https://petstore.swagger.io/v2/pet/{petId}'

foreach ($workflow->do as $name => $task) {
// ...
}
```

### Convert to JSON/YAML

```php
$json = $workflow->toJson();

$yaml = $workflow->toYaml();

$array = $workflow->toArray();
```

## Validate

```php
use Serverless\Workflow\WorkflowValidationException;
use Serverless\Workflow\WorkflowValidator;

WorkflowValidator::validate($workflow);
try {
$workflow->validate(); // or WorkflowValidator::validate($workflow);
} catch (WorkflowValidationException $exception) {
foreach ($exception->getErrors() as $pointer => $messages) {
// '/document' => ['The required properties (version) are missing']
}
}

$errors = WorkflowValidator::errors($workflow); // [] when valid
```

The `validate` method will raise an exception if the provided workflow does not comply with the specification.
Validation uses the DSL JSON schema bundled in [`schema/workflow.json`](schema/workflow.json), so it works
offline. Raw arrays can be validated too: `WorkflowValidator::errors(Yaml::parse($yaml))`.

## Development

```bash
composer install
composer run-script ecs # fix coding style
composer run-script stan # static analysis
composer run-script test # test suite
```

## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fopen-workflow-specification%2Fsdk-php.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fopen-workflow-specification%2Fsdk-php?ref=badge_large)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fopen-workflow-specification%2Fsdk-php.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fopen-workflow-specification%2Fsdk-php?ref=badge_large)
32 changes: 22 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,40 @@
{
"name": "serverlessworkflow/sdk",
"description": "Provides the PHP API/SPI for the Serverless Workflow Specification.",
"description": "Provides the PHP API/SPI for the Open Workflow Specification (formerly Serverless Workflow Specification).",
"type": "library",
"license": "Apache-2.0",
"autoload": {
"psr-4": {
"Serverless\\Workflow\\": "src/"
}
},
"keywords": [
"workflow",
"serverless-workflow",
"open-workflow-specification",
"dsl"
],
"homepage": "https://github.com/open-workflow-specification/sdk-php",
"authors": [
{
"name": "Serverless Workflow Specification Authors"
}
],
"require": {
"php": "^8.2",
"opis/json-schema": "^2.4",
"symfony/yaml": "^6.4 || ^7.0"
},
"require-dev": {
"phpstan/phpstan": "^1.9",
"phpunit/phpunit": "^10.4",
"rector/rector": "^0.18.10",
"symplify/easy-coding-standard": "^11.1"
},
"require": {
"symfony/yaml": "^6.3",
"phpdocumentor/reflection-docblock": "^5.3",
"swaggest/json-schema": "^0.12.42"
"autoload": {
"psr-4": {
"Serverless\\Workflow\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Serverless\\Workflow\\Tests\\": "tests/"
}
},
"scripts": {
"rector": "vendor/bin/rector",
Expand Down
Loading
Loading