Skip to main content

Overview

Serverless Workflow DSL is designed to seamlessly interact with a variety of services, ensuring robust service interoperability. Whether you’re working with REST APIs, gRPC services, event-driven architectures, or custom integrations, the DSL provides the tools you need.

Supported Protocols

The Serverless Workflow DSL supports several standard protocols out of the box:

HTTP

Allows the workflow to make standard HTTP requests to web services. This is useful for RESTful services and web APIs that communicate over the HTTP protocol.
do:
  - getUserData:
      call: http
      with:
        method: get
        endpoint:
          uri: https://api.example.com/users/123

gRPC

Supports Remote Procedure Call (RPC) using gRPC, a high-performance, open-source universal RPC framework. This is suitable for connecting to services that require low-latency and high-throughput communication.
do:
  - callGrpcService:
      call: grpc
      with:
        proto:
          uri: https://example.com/protos/service.proto
        service:
          name: MyService
          host: grpc.example.com
          port: 9090
        method: GetUser

AsyncAPI

Facilitates interaction with asynchronous messaging protocols. AsyncAPI is designed for event-driven architectures, allowing workflows to publish and subscribe to events.
do:
  - publishEvent:
      call: asyncapi
      with:
        document:
          uri: https://example.com/asyncapi.yaml
        operationRef: sendMessage

OpenAPI

Enables communication with services that provide OpenAPI specifications, which is useful for defining and consuming RESTful APIs.
do:
  - callOpenApiService:
      call: openapi
      with:
        document:
          uri: https://petstore.swagger.io/v2/swagger.json
        operationId: getPetById
        parameters:
          petId: 123

A2A

Enables interaction with A2A servers (agents described by A2A).
do:
  - callAgent:
      call: a2a
      with:
        endpoint:
          uri: https://agent.example.com
        task: processData
Runtimes must raise an error with type https://serverlessworkflow.io/spec/1.0.0/errors/communication if and when a problem occurs during a call.

Custom and Non-Standard Interactions

In addition to the default supported protocols, the DSL also provides mechanisms to interact with services in non-standard or unsupported ways using custom processes. This flexibility allows workflows to extend their capabilities beyond the built-in protocols and integrate with any service, regardless of the communication method. For custom interactions, the workflow can define tasks that:
  • Execute shell commands
  • Execute scripts
  • Run containers
This ensures that the workflow can still maintain interoperability even with services that do not adhere to the standard supported protocols.

Creating a Custom Function

1

Create Function Directory

In your repository, create a new directory for your function, for example, /serverless-workflow/functions/my-custom-function.It is strongly recommended that custom function authors include the semantic version of the function in its path. For instance, you might structure the path as /serverless-workflow/functions/my-custom-function/1.0.0 to reflect the function’s version.
2

Define the Function

Create a function.yaml file containing the function’s definition. Ideally, the function should document both its input and output. This is important for documentation and validation purposes.
# function.yaml
input:
  schema:
    document:
      type: object
      description: The function's input
      properties:
        emailAddress:
          type: string
          description: The email address to validate.
output:
  schema:
    document:
      type: object
      description: The function's output
      properties:
        isValid:
          type: boolean
          description: A boolean indicating whether or not the email address is valid.
run:
  script:
    language: javascript
    code: |
      function validateEmail(email) {
        const re = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
        return re.test(email);
      }
      return { isValid: validateEmail(emailAddress) };
    arguments:
      emailAddress: ${ .emailAddress }
3

Add Supporting Files

Optionally, add all the local files your function might need into its directory.
4

Commit and Push

Commit and push your function to your repository.
5

Publish to Catalog (Optional)

Optionally, submit your function to the Serverless Workflow Catalog, allowing users to find your function.
For more information about authoring a new custom function, visit the Serverless Workflow Catalog.

Using a Custom Function

Once a custom function is defined, it can be used within a workflow to perform specific tasks. The following example demonstrates how to use the validateEmailAddress custom function in a workflow:
# workflow.yaml
document:
  dsl: '1.0.3'
  namespace: default
  name: customFunctionWorkflow
  version: '0.1.0'
do:
  - validateEmail:
      call: https://github.com/myorg/functions/[email protected]
      with:
        emailAddress: ${ .userEmail }

Publishing a Custom Function

Consider submitting your function to the Serverless Workflow Function Catalog. This optional step allows users to discover and utilize your function, enhancing its visibility and usability within the Serverless Workflow community. By registering your function, you contribute to a shared repository of resources that can streamline workflow development for others. For detailed instructions on how to contribute your custom function, please refer to the CONTRIBUTING.md file.

Frequently Asked Questions

  • Use HTTP for RESTful APIs and standard web services
  • Use gRPC for high-performance, low-latency service-to-service communication
  • Use AsyncAPI for event-driven architectures and message brokers
  • Use OpenAPI when you have an OpenAPI specification for your service
  • Use custom functions for proprietary protocols or complex integrations
Yes! A workflow can call different services using different protocols. Each task can specify its own call type (HTTP, gRPC, AsyncAPI, etc.).
When a call fails, the runtime raises a communication error with type https://serverlessworkflow.io/spec/1.0.0/errors/communication. You can handle these errors using the try/catch mechanism and implement retry strategies as needed.
Yes! Custom functions can orchestrate multiple service calls, perform data transformations, or implement complex business logic. The function definition can include multiple tasks that call different services using various protocols.

Build docs developers (and LLMs) love