> For the complete documentation index, see [llms.txt](https://docs.stoobly.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stoobly.com/core-concepts/scaffold/workflow.md).

# Workflow

A workflow groups configurations for services to perform distinct use cases. By default, Stoobly provides configurations for four workflows: record, mock, test, and develop. Use `--workflow` when creating a service to select a subset instead of all four (see the [Scaffold FAQ](/faq/scaffold.md) for details).

## Background

To learn more about the role of individual services, see:

{% content-ref url="/pages/CV2FP4ZBSIpH9GCwJxyX" %}
[Service](/core-concepts/scaffold/service.md)
{% endcontent-ref %}

To run a workflow, see:

{% content-ref url="/pages/7J10qWFxe9zweKA3YQtH" %}
[How to Run a Workflow](/guides/how-to-integrate-e2e-testing/how-to-run-a-workflow.md)
{% endcontent-ref %}

To validate a workflow, see:

{% content-ref url="/pages/mrxE2H3fxfCSRj8hF0QQ" %}
[Validation](/core-concepts/scaffold/validation.md)
{% endcontent-ref %}

## File Structure

{% hint style="info" %}
To learn how each file is used, see [here](/core-concepts/scaffold/service.md#containers).
{% endhint %}

{% hint style="warning" %}
Any hidden file will be overritten when the scaffold service create command is rerun.
{% endhint %}

<details>

<summary>bin/init</summary>

First script that executes when a workflow runs. Should contain any commands needed for the service to initialize. Can also contain configuration commands for Stoobly. See [filter rules](/core-concepts/agent/proxy-settings/filter-rules.md), [match rules](/core-concepts/agent/proxy-settings/match-rules.md), and [rewrite rules](/core-concepts/agent/proxy-settings/rewrite-rules.md).

</details>

<details>

<summary>bin/.init</summary>

Maintained file that will be overriden on scaffold create.

</details>

<details>

<summary>docker-compose.yml</summary>

Custom docker-compose.yml file. Container services defined in this should should include:

* Respective `<WORKFLOW-NAME>` under the `profiles` property
* Either `app.egress` or `app.ingress` under the `networks` property

</details>

<details>

<summary>.docker-compose.&#x3C;WORKFLOW-NAME>.yml</summary>

Maintained file that will be overriden on scaffold create.

</details>

<details>

<summary>fixtures.yml</summary>

Enables defining mock responses for specific URL patterns. To learn more see [here](/core-concepts/mock-api/fixtures.md).

</details>

<details>

<summary>lifecycle_hooks.py</summary>

Enables reading and modifying requests during specific points in their lifecycle. To learn more see [here](/core-concepts/agent/lifecycle-hooks.md).

</details>

<details>

<summary>public</summary>

Enables defining mock request paths and responses using files stored in this folder. To learn more see [here](/core-concepts/mock-api/public-folder.md).

</details>

## Core Workflows

### Record

<figure><img src="/files/WGwtUwZxrplo52GmnOpW" alt=""><figcaption><p>Flow diagram for recording requests</p></figcaption></figure>

The journey of a request:

1. A request gets sent from the host e.g. browser or cURL
2. Gets sent to the gateway service
3. Gateway service routes the request based on hostname
4. Request gets intercepted by Stoobly running as a proxy
   1. Lifecycle hooks get triggered
5. Stoobly reverse proxies the request to the local or external API
6. On response, Stoobly records the request to its respective `.stoobly`folder
   1. Lifecycle hooks get triggered

### Mock

<figure><img src="/files/ftPAP5QoKPl0uLI3ijNd" alt=""><figcaption><p>Flow diagram for mocking requests</p></figcaption></figure>

The journey of a request:

1. A request gets sent from the host e.g. browser or cURL
2. Gets sent to the gateway service
3. Gateway service routes the request based on hostname
4. Request gets intercepted by Stoobly running as a proxy
   1. Lifecycle hooks get triggered
5. Stoobly mocks requests if it has been previously recorded. If the request is not found, it can conditionally reverse proxy the request to the local or external API
   1. Lifecycle hooks get triggered

### Test

<figure><img src="/files/6oPIduIpIncGYnAaaLSr" alt=""><figcaption><p>Flow diagram for testing an application that sends requests</p></figcaption></figure>

The journey of a request:

1. A request gets sent from the entrypoint service
2. Gateway service routes the request based on hostname
3. Request gets intercepted by Stoobly running as a proxy
   1. Lifecycle hooks get triggered
4. Stoobly mocks requests if it has been previously recorded. If the request is not found, it can conditionally reverse proxy the request to the local or external API
   1. Lifecycle hooks get triggered

### Develop

Unlike record, mock, and test, the develop workflow isn't about capturing or replaying fixed responses.

It's for working against a service's real hostname (e.g. an endpoint your app already calls in staging or production) while transparently redirecting requests to a local development server.

This redirection is driven by [rewrite rules](/core-concepts/agent/proxy-settings/rewrite-rules.md) generated from the service's configured upstream hostname, port, and scheme. Whenever a service's upstream configuration changes, resync its develop rewrite rules with:

```bash
stoobly-agent scaffold workflow rewrite develop
```

The journey of a request:

1. A request gets sent from the host e.g. browser or cURL
2. Gets sent to the gateway service
3. Gateway service routes the request based on hostname
4. Request gets intercepted by Stoobly running as a proxy
   1. Lifecycle hooks get triggered
5. Stoobly rewrites the request, redirecting it from the service's original upstream hostname, port, and scheme to the local development target defined by the synced rewrite rules
6. Stoobly reverse proxies the rewritten request to the local development server and returns its response to the host
   1. Lifecycle hooks get triggered

`develop` is created automatically along with record, mock, and test whenever you run `scaffold service create` without a `--workflow` filter:

```bash
# Creates record, mock, test, AND develop workflows for the service
stoobly-agent scaffold service create api

# To create only a subset, list the workflows you want explicitly
stoobly-agent scaffold service create api --workflow mock --workflow test

# Or add develop to an existing service that was scaffolded with a subset
stoobly-agent scaffold workflow create develop --template develop --service api
```
