Flow dependencies, export, and import
Flow definition requests (POST /api/v1/flows and PUT /api/v1/flows/{id})
accept bodies up to 50 MiB, including whitespace. A larger body returns 413
without creating or updating the flow. Reduce the document before retrying.
Dependencies
A flow can declare the flows it needs with dependsOn (a list of flow ids):
{"id": "adt-archive", "name": "ADT archive", "dependsOn": ["adt"]}
The server checks dependencies on create, update, and import. It returns 400 when:
| Problem | Example message |
|---|---|
| A listed flow does not exist | flow adt-archive depends on unknown flow adt |
| A flow lists itself | flow adt cannot depend on itself |
| The dependencies form a loop | dependency cycle: a -> b -> a |
You cannot delete a flow that another flow depends on:
409 {"error":{"code":"CONFLICT","message":"flow is a dependency of other flows: adt depended on by adt-archive"}}
To prove nothing depends on it, the server must be able to read every other flow. If one is
unreadable, the delete returns 500 naming that flow; delete the unreadable flow first (a flow
can always delete itself).
Deploying a flow, manually or through startup auto-deploy, also deploys every undeployed flow
it depends on, dependencies first. Dependencies in any other status are left as they are, so
deploying a dependent never interrupts a running dependency. Starting a flow does not start its
dependencies. See Flow lifecycle.
Export
GET /api/v1/flows/export (permission flows:view) returns flow definitions:
curl -s -u 'admin:PASSWORD' -H 'X-Weavster-CSRF: 1' \
'http://127.0.0.1:8080/api/v1/flows/export?ids=adt-archive' > flows.json
{"version":1,"flows":[
{"id":"adt","name":"ADT normalize","sourceType":"http","enabled":true,"transform":{…},"destinations":[…]},
{"id":"adt-archive","name":"ADT archive","sourceType":"","enabled":false,"dependsOn":["adt"]}
]}
idsis a comma-separated list. The export also includes every flow those flows depend on, directly or indirectly. Leaveidsout to export all flows.- Flows are sorted by id and have no
status: an export holds definitions, not runtime state. - An unknown id returns
404.
Import
POST /api/v1/flows/import (permission flows:edit) takes an export document:
curl -s -u 'admin:PASSWORD' -H 'X-Weavster-CSRF: 1' -X POST \
http://127.0.0.1:8080/api/v1/flows/import --data @flows.json
{"created":["adt","adt-archive"],"updated":[]}
The whole document is checked before anything is written. Every flow must be valid, the ids
must be unique, and dependencies must resolve against the document plus the existing flows,
without cycles. Otherwise the import returns 400 and changes nothing. Flows are then written
dependencies first. Each flow in the document is a full definition: a flow without enabled
is imported disabled. Exports always include enabled.
| Flow in the document | Result |
|---|---|
| New id | Created undeployed. Deploy and start it to process messages. |
Existing id, without ?overwrite=true |
Nothing is written: 409 flows already exist: adt (use overwrite=true to replace them). Checked after the document is validated, so an invalid document returns 400 even when it also conflicts. |
Existing id, with ?overwrite=true |
Definition replaced; the flow keeps its current status. |
Other errors:
| Response | Cause |
|---|---|
400 unsupported export version 2; expected 1 |
Missing or unknown version. |
400 flows[0]: status is managed by lifecycle operations …; omit it |
A flow in the document has a status field. |
400 flows[0]: stoppedDestinations is managed by …; omit it |
A flow in the document has a stoppedDestinations field. |
400 … appears twice |
The same id is listed twice. |
400 body must be an export document |
Not a JSON object, no flows array, a top-level field other than version and flows, or extra data after the document. |
413 |
The document is larger than 50 MiB. |
If writing fails part-way (for example, a store error), the import stops and returns
500 {"error":{"code":"IMPORT_INCOMPLETE",…},"created":[…],"updated":[…]}, listing what was
written. Because flows are written dependencies first, every written flow's dependencies exist.
Import again with ?overwrite=true to finish.
Creates, updates, imports, and deletes of flow definitions run one at a time, so a dependency check always sees the flows it is written against.
Reserved ids
export, import, redeploy-all, connector-names, ports-in-use, stats, and deploy-all, undeploy-all, start-all, stop-all, pause-all, halt-all, resume-all cannot be used as flow ids, because they name these
endpoints. A flow created with one of these ids before this rule existed can still be deleted
(DELETE /api/v1/flows/export). To keep it, export all flows, change its id in the file,
delete it, and import the file.