What is ADL?

Agnostic Development Language (ADL)

ADL (/əˈdɛl/) is short for Agnostic Development Language, a dynamic computer programming language created to simplify programming. It leverages a well-known "boxes-and-arrows" metaphor used in applications such as OmniGraffle and Microsoft Visio. ADL is intended to enable developers, at any level of expertise, to build programs visually by using logical flows instead lines of code. Developing ADL on Graph is organized into 3 functional groups: the workspace, the live documentation and the actual code.

 

{ }

Example Response

{}

Workspace

The Workspace is the stage or your canvas to work. You'll place and connect elements to create code. ADL uses similar metaphors to traditional drawing and flow-chart applications where there's a workspace that has tools which manipulate elements.

 

{ }

Example Response

{}

Tools

Your workspace tools are organized in a palette displays as a movable vertical palette in your workspace. Like using Adobe Illustrator or Photoshop you start by selecting a desired tool and then click on the workspace to add it to your code.

 

{ }

Example Response

{}

Elements

Elements are visual representations of the code you're developing. Each ADL view is constructed of elements that are connected by lines. The flow of lines to elements determines the process a view runs in ADL. The lines have arrows at one end to guide you down the development path.

 

{ }

Example Response

{}

Info

The info palette is your window into the data and actions you can do using elements created via the tools. You create, save, update and delete data in this palette.

 

{ }

Example Response

{}

Data Editor

All data is returned via a "Data Editor" palette that appears only when you need it. The data is displayed using JSON. It's formatted to make it as simple as possible to view and understand.

 

{ }

Example Response

{}

Putting ADL to Use

Data & Variables

Values

ADL utilizes 4 types of primitive values.

  • Logicals/booleans (true|false)
  • Numbers (42, 3.14159)
  • Text/strings ("Hello world")
  • <empty> (null|None)


You use variables as symbolic names for values in your application. The names of variables, called identifiers, conform to certain rules.

An variable can start with any ASCII character, uppercase or lowercase.In addition to the Values listed above, Variables can also store lists/arrays and dicts/objects.

 

{ }
[{"data":{"type":"variable","step":"my_bool = true","var":"my_bool","val":true,"maxpaths":1,"uuid":"ele1","x":0,"y":0,"width":120,"height":32},"paths":["ele2"]},{"data":{"type":"variable","step":"my_number = 42","var":"my_number","val":42,"maxpaths":1,"uuid":"ele2","x":0,"y":80,"width":120,"height":32},"paths":["ele3"]},{"data":{"type":"variable","step":"my_string = 'Hello world'","var":"my_string","val":"Hello world","maxpaths":1,"uuid":"ele3","x":0,"y":160,"width":120,"height":32},"paths":["ele4"]},{"data":{"type":"variable","step":"my_empty","var":"my_empty","val":"","maxpaths":1,"uuid":"ele4","x":0,"y":240,"width":120,"height":32},"paths":[]}]

Example Response

{}

Data type conversion

ADL is a dynamically typed language. Meaning, you don't have to specify the data type of a variable when you declare it, and data types are converted automatically as needed during script execution. So, for example, you could define a variable as follows:

var answer = 42;

And later, you could assign the same variable a string value, for example:

answer = "May the force be with you..";

Because ADL is dynamically typed, this assignment does not raise an error.

In expressions involving numeric and string values with the + operator, ADL converts numeric values to strings. For example, consider the following statements:

x = "The answer is " + 42 // "The answer is 42"
y = 42 + " is the answer" // "42 is the answer"


In statements involving other operators, ADL does not convert numeric values to strings. For example:

"37" - 7 // 30"37" + 7 // "377"

Main flow

{ }
[{"data":{"type":"variable","step":"answer = 42","var":"answer","val":42,"maxpaths":1,"uuid":"ele1","x":0,"y":0,"width":120,"height":32},"paths":[]}]

Example Response

{}

Update variable flow

[{"data":{"type":"variable","step":"answer = 42","var":"answer","val":42,"maxpaths":1,"uuid":"ele1","x":0,"y":0,"width":120,"height":32},"paths":["ele2"]},{"data":{"type":"variable","step":"answer = 'May the force be with you...'","var":"May the force be with you...","val":42,"maxpaths":1,"uuid":"ele2","x":0,"y":80,"width":120,"height":32},"paths":[]}]

Lists/arrays

A list/array is a list of zero or more expressions, each of which represents an array element, enclosed in square brackets ([]). When you create an array, it is initialized with the specified values as its elements, and its length is set to the number of arguments specified.

The example at right creates an variable named 'coffees' and stores a list/array in it with three elements and a length of three.

 

{ }
[{"data":{"type":"variable","step":"'coffees' list\/array","var":"coffees","val":"[\"French Roast\", \"Colombian\", \"Kona\"]","maxpaths":1,"uuid":"d7db099a1a3f9e2df693cd4422bb26cb","x":0,"y":0,"width":120,"height":32},"paths":[]}]

Example Response

{"coffees":["French Roast","Colombian","Kona"]}

Dicts/objects

An object is a list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({}).

The example at right creates an variable named 'coffee & tea' and stores a dict/object in it with 2 key/value pairs elements and a length of two.

 

{ }
[{"data":{"type":"variable","step":"'coffee & tea' dict\/object","var":"coffees","val":"{\"Kona\":\"coffee\",\"Earl Grey\":\"tea\"}","maxpaths":1,"uuid":"d7db099a1a3f9e2df693cd4422bb26cb","x":0,"y":0,"width":120,"height":32},"paths":[]}]

Example Response

{"Kona":"coffee","Earl Grey":"tea"}

Getting data

To use values stored in a variable in ADL, you simply need to drag the variable from the "Variables" palette to the desired field you want to use the data in the "Info" palette.

 

{ }
[{"paths":["9105310d3521caac02031125e66e066d"],"data":{"uuid":"640cc9a1dd7ae3878d61146ebf77a211","val":"Hello world!","width":120,"height":32,"y":0,"step":"my_var = 'Hello world!'","var":"my_var","x":0,"type":"variable","maxpaths":1}},{"paths":[],"data":{"uuid":"9105310d3521caac02031125e66e066d","data":"{\"~\":\"my_var\"}","height":32,"width":120,"step":"Return my_var","y":80,"x":0,"type":"return","maxpaths":0}}]

Example Response

{"my_var":"Hello world!"}

Statements and controlling flow

Conditional statements (if/else)

Decision making structures (ala "if" statements) require that the programmer specify one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false. If statements, in ADL, are very similar to those in other popular programming languages. The only difference is that ADL doesn't currently support "elseif" or statements. That doesn't mean you can handle possibly conditional states that didn't match the first. Only that you have to set them up a little differently that when writing traditional code.

This example examines the variable 'x' (which is set to 100) and evaluates if the value is == to 100 (as it is set in the if statement. If so, the "Success" path is taken and the "return" directive is run returning the text 'x is 100!!!' Otherwise the "Failure" path is taken and the "return" directive is run returning the text 'x is not 100 :('

ADL if statements support as many conditions as you would like to define. A condition examines 2 values and evalues them based on a defined comparison.

Available comparisons are

  • equals (==)
  • does not equal (!= or <>)
  • greater than (>)
  • greater than or equal to (>=)
  • less than (<)
  • less than than or equal to (<=)

 

{ }
[{"paths":["149dfcf13aa063293a377e8bf2beb2e0"],"data":{"uuid":"640cc9a1dd7ae3878d61146ebf77a211","val":100,"width":120,"height":32,"step":"Create x = 100","var":"my_list","x":80,"y":0,"type":"variable","maxpaths":1}},{"paths":["4b1062302c5e54868ecd200aefb7fc9c","f512613274c0e14f5e2bad1acbc5d275"],"data":{"type":"conditional","step":"Does x == 100","conditions":[{"var":{"~":"x"},"cond":null,"value":100,"cmp":"=="}],"success":[],"failure":[],"maxpaths":2,"uuid":"149dfcf13aa063293a377e8bf2beb2e0","width":120,"height":32,"x":80,"y":80}},{"paths":[],"data":{"type":"return","step":"Return x is 100","maxpaths":0,"uuid":"4b1062302c5e54868ecd200aefb7fc9c","height":32,"width":120,"x":0,"y":160,"data":"x is 100!!!"}},{"paths":[],"data":{"type":"return","step":"Return x is not 100","maxpaths":0,"uuid":"f512613274c0e14f5e2bad1acbc5d275","height":32,"width":120,"x":160,"y":160,"data":"x is not 100 :("}}]

Example Response

{"data":"x is 100!!!"}

"While" loops

A while statement executes its statements as long as a specified condition evaluates to true. If the condition becomes false, the flow within the loop stops executing and control passes to the statement following the loop.

The condition test occurs before the flow in the loop is executed. If the condition returns true, the flow is executed and the condition is tested again. If the condition returns false, execution stops and control is passed to the statement following the while loop.

Main flow

{ }
[{"data":{"type":"variable","var":"while_val","step":"set while_val = 0 ","val":0,"maxpaths":1,"uuid":"5c71ff91ea95b178c25036c5b465a7b7","x":0,"y":0,"width":120,"height":32},"paths":["d634c30298f0b900183bf7907a1f99b1"]},{"data":{"type":"variable","var":"agg","step":"set agg = ''","val":"","maxpaths":1,"uuid":"d634c30298f0b900183bf7907a1f99b1","x":0,"y":80,"width":120,"height":32},"paths":["64a3345e00ac7167875783b9ed5ce4a9"]},{"data":{"type":"loop","step":"Do loop while while_val < 3 ","looptype":"while","init":[],"conditions":[{"var":{"~":"while_val"},"cmp":"<","value":3,"cond":null}],"after":[],"callstack":[{"data":{"type":"library","step":"increment while_val","call":"operators.arithmetic.++","args":{"item":"{\"~\":\"while_val\"}"},"data_to_var":null,"maxpaths":1,"uuid":"3692c57324b486d8c72c0681d6a6824d","x":565,"y":192,"width":120,"height":42,"math":"math","operators":"operators","operators.arithmetic.++":"++"},"paths":["2521eaf329d5b98bc2d61c3e44a1f68f"]},{"data":{"type":"library","step":"add to agg","call":"operators.arithmetic.+","args":{"item1":"{\"~\":\"agg\"}","item2":"hello"},"data_to_var":"{\"~\":\"agg\"}","maxpaths":1,"uuid":"2521eaf329d5b98bc2d61c3e44a1f68f","x":566,"y":264,"width":120,"height":32,"operators":"operators"},"paths":[]}],"maxpaths":1,"uuid":"64a3345e00ac7167875783b9ed5ce4a9","x":0,"y":160,"width":120,"height":32},"paths":[]}]

Example Response

{"agg":"hello.hello.hello."}

do flow

[{"data":{"type":"library","step":"increment while_val","call":"operators.arithmetic.++","args":{"item":"{\"~\":\"while_val\"}"},"data_to_var":null,"maxpaths":1,"uuid":"3692c57324b486d8c72c0681d6a6824d","x":0,"y":0,"width":120,"height":42,"math":"math","operators":"operators","operators.arithmetic.++":"++"},"paths":["2521eaf329d5b98bc2d61c3e44a1f68f"]},{"data":{"type":"library","step":"add to agg","call":"operators.arithmetic.+","args":{"item1":"{\"~\":\"agg\"}","item2":"hello"},"data_to_var":"{\"~\":\"agg\"}","maxpaths":1,"uuid":"2521eaf329d5b98bc2d61c3e44a1f68f","x":0,"y":80,"width":120,"height":32,"operators":"operators"},"paths":[]}]

"Times" loops

A "times" statement executes its statements for a specified number of times. Once the loop has executed the specified number of times, it stops executing and control passes to the statement following the loop. In this example,we achieve exactly what we did in the "while" loop above. Just using less ADL.

Main flow

{ }
[{"data":{"type":"variable","var":"agg","step":"set agg = ''","val":"","maxpaths":1,"uuid":"d634c30298f0b900183bf7907a1f99b1","x":0,"y":0,"width":120,"height":32},"paths":["51ef1a211465ceef0980de68564d65a2"]},{"paths":[],"data":{"callstack":[{"data":{"type":"library","step":"add to agg","call":"operators.arithmetic.+","args":{"item1":"{\"~\":\"agg\"}","item2":"hello"},"data_to_var":"{\"~\":\"agg\"}","maxpaths":1,"uuid":"2521eaf329d5b98bc2d61c3e44a1f68f","x":0,"y":0,"width":120,"height":32,"operators":"operators"},"paths":[]}],"uuid":"51ef1a211465ceef0980de68564d65a2","type":"loop","looptype":"loop","after":[],"init":[],"times":3,"width":120,"step":"Do loop 3 times","y":80,"x":0,"height":32,"conditions":[],"maxpaths":1}}]

Example Response

{"agg":"hello.hello.hello."}

do flow

[{"data":{"type":"library","step":"add to agg","call":"operators.arithmetic.+","args":{"item1":"{\"~\":\"agg\"}","item2":"hello"},"data_to_var":"{\"~\":\"agg\"}","maxpaths":1,"uuid":"2521eaf329d5b98bc2d61c3e44a1f68f","x":0,"y":0,"width":120,"height":32,"operators":"operators"},"paths":[]}]

"For each" loops

The "for each" statement in ADL is a quick and easy way to iterate over a sequence of things. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), ADL's "for each" statement iterates over the items of any sequence (a list/array, a dict/object, or a string), in the order that they appear in the sequence.

When iterating on lists/arrays or strings, a reserved local variable named 'item' is added to your flow so you can access the currently iterated on 'item.'

Similarly, when iterating on a dict/object, 2 reserved local variables are added to your flow. They are 'k' (for key) and 'v' (for value).

Main flow

{ }
[{"paths":["d634c30298f0b900183bf7907a1f99b1"],"data":{"uuid":"7b47e215c347ae04f9070c07fde68a34","val":"","width":120,"height":32,"step":"agg","var":"agg","x":0,"y":0,"type":"variable","maxpaths":1}},{"paths":["dc78d61eeb5b61be2869a572d755f1aa"],"data":{"uuid":"d634c30298f0b900183bf7907a1f99b1","val":["Hello ","World, ","I'm ADL!"],"height":32,"width":120,"step":"list","var":"list","type":"variable","x":0,"y":80,"maxpaths":1}},{"paths":[],"data":{"callstack":[{"data":{"type":"library","step":"add to agg","call":"operators.arithmetic.+","args":{"item1":"{\"~\":\"agg\"}","item2":"{\"~\":\"item\"}"},"data_to_var":"{\"~\":\"agg\"}","maxpaths":1,"uuid":"2521eaf329d5b98bc2d61c3e44a1f68f","x":0,"y":0,"width":120,"height":32,"operators":"operators"},"paths":[]}],"uuid":"dc78d61eeb5b61be2869a572d755f1aa","type":"loop","looptype":"each","after":[],"init":[],"height":32,"width":120,"step":"For each item in 'list'","items":{"~":"list"},"x":0,"y":160,"conditions":[],"maxpaths":1}}]

Example Response

{"data":"Hello World, I'm ADL!"}

do flow

[{"data":{"type":"library","step":"add to agg","call":"operators.arithmetic.+","args":{"item1":"{\"~\":\"agg\"}","item2":"{\"~\":\"item\"}"},"data_to_var":"{\"~\":\"agg\"}","maxpaths":1,"uuid":"2521eaf329d5b98bc2d61c3e44a1f68f","x":0,"y":0,"width":120,"height":32,"operators":"operators"},"paths":[]}]

Advanced "for" loops

A for loop repeats until a specified condition evaluates to false. The META structure for an ADL "Advanced for" loop is similar to the Javascript, PHP, Java and C "for" loop.

    A "for" statement contains:
  • an initializing flow (init)
  • a condition to satisfy to continue looping (condition)
  • a flow to execute for each loop (do)
  • a loop that executes after each loop (after)

When a for loop executes, the following occurs:
  1. The initializing flow (init), if any, is executed. This expression usually initializes one or more loop counters, but the syntax allows an expression of any degree of complexity. This expression can also declare variables.
  2. The condition expression is evaluated. If the value of condition is true, the loop statements execute. If the value of condition is false, the for loop terminates. If the condition expression is omitted entirely, the condition is assumed to be true.
  3. The (do) flow executes.
  4. The update (after) flow, if there is one, executes, and control returns to step 2.

Main flow

{ }
[{"paths":["d634c30298f0b900183bf7907a1f99b1"],"data":{"uuid":"7b47e215c347ae04f9070c07fde68a34","val":"","width":120,"height":32,"step":"agg","var":"agg","x":0,"y":0,"type":"variable","maxpaths":1}},{"paths":["b4792505a9e83cd1277f7f9be69056c1"],"data":{"uuid":"d634c30298f0b900183bf7907a1f99b1","val":["Hello","World,","I'm ADL!"],"height":32,"width":120,"step":"list","var":"list","type":"variable","x":0,"y":80,"maxpaths":1}},{"paths":[],"data":{"callstack":[{"paths":["320a201630ccbbec48d54400adfc7da0"],"data":{"args":{"list":"{\"~\":\"list\"}"},"uuid":"8e7666109eb438cb26a725293efe6e6a","height":32,"width":120,"step":"Set 'tmp' using list element","list\/array":"list\/array","list\/array.get":"get","call":"list\/array.get","data_to_var":"tmp","x":0,"y":0,"type":"library","maxpaths":1}},{"paths":["e5e90a2942e4c57fa6c38e2fbbcc2aa8"],"data":{"uuid":"320a201630ccbbec48d54400adfc7da0","operators":"operators","args":{"item1":"{\"~\":\"agg\"}","item2":" "},"height":32,"width":120,"step":"Add a space...","call":"operators.arithmetic.+","data_to_var":"{\"~\":\"agg\"}","x":0,"y":80,"type":"library","maxpaths":1}},{"paths":[],"data":{"uuid":"e5e90a2942e4c57fa6c38e2fbbcc2aa8","operators":"operators","args":{"item1":"{\"~\":\"agg\"}","item2":"{\"~\":\"tmp\"}"},"height":32,"width":120,"step":"Add 'tmp' to 'agg'","call":"operators.arithmetic.+","data_to_var":"{\"~\":\"agg\"}","x":0,"y":160,"type":"library","maxpaths":1}}],"uuid":"b4792505a9e83cd1277f7f9be69056c1","type":"loop","looptype":"for","init":[{"paths":[],"data":{"uuid":"5551750cb1534532e3386f872e93ddbb","val":0,"width":120,"height":32,"step":"set 'i' = 0","var":"i","x":0,"y":0,"type":"variable","maxpaths":1}}],"after":[{"data":{"type":"library","step":"Increment 'i'","call":"operators.arithmetic.++","args":{"item":"{\"~\":\"i\"}"},"data_to_var":"","maxpaths":1,"uuid":"aee7a98c47f31a00cabc0f9b8db3bd04","x":0,"y":0,"width":120,"height":32,"operators":"operators","operators.arithmetic.++":"++"},"paths":[]}],"height":32,"width":120,"step":"Do Loop","x":0,"y":160,"conditions":[{"var":{"~":"i"},"cond":null,"value":3,"cmp":"<"}],"maxpaths":1}}]

Example Response

{"data":"Hello World, I'm ADL!"}

init flow

[{"paths":[],"data":{"uuid":"5551750cb1534532e3386f872e93ddbb","val":0,"width":120,"height":32,"step":"set 'i' = 0","var":"i","x":0,"y":0,"type":"variable","maxpaths":1}}]

do flow

[{"paths":["320a201630ccbbec48d54400adfc7da0"],"data":{"args":{"list":"{\"~\":\"list\"}"},"uuid":"8e7666109eb438cb26a725293efe6e6a","height":32,"width":120,"step":"Set 'tmp' using list element","list\/array":"list\/array","list\/array.get":"get","call":"list\/array.get","data_to_var":"tmp","x":0,"y":0,"type":"library","maxpaths":1}},{"paths":["e5e90a2942e4c57fa6c38e2fbbcc2aa8"],"data":{"uuid":"320a201630ccbbec48d54400adfc7da0","operators":"operators","args":{"item1":"{\"~\":\"agg\"}","item2":" "},"height":32,"width":120,"step":"Add a space...","call":"operators.arithmetic.+","data_to_var":"{\"~\":\"agg\"}","x":0,"y":80,"type":"library","maxpaths":1}},{"paths":[],"data":{"uuid":"e5e90a2942e4c57fa6c38e2fbbcc2aa8","operators":"operators","args":{"item1":"{\"~\":\"agg\"}","item2":"{\"~\":\"tmp\"}"},"height":32,"width":120,"step":"Add 'tmp' to 'agg'","call":"operators.arithmetic.+","data_to_var":"{\"~\":\"agg\"}","x":0,"y":160,"type":"library","maxpaths":1}}]

after flow

[{"data":{"type":"library","step":"Increment 'i'","call":"operators.arithmetic.++","args":{"item":"{\"~\":\"i\"}"},"data_to_var":"","maxpaths":1,"uuid":"aee7a98c47f31a00cabc0f9b8db3bd04","x":0,"y":0,"width":120,"height":32,"operators":"operators","operators.arithmetic.++":"++"},"paths":[]}]

Standard library

ADL features a fully-formed functional standard library reminiscent of all modern programming languages. You just used visual elements to control the programmatic flow and access data.

The Standard Library has been organized in a simple easy-to-consume manner to you can find what you need as quickly as possible and use it immediately in your ADL.

 

{ }

Example Response

{}

Plugins

How do plugins work?

Plugins are pre-built turnkey functional packages that eliminate the need to replicate things that have been done, and done well time after time in software development. The, in many ways, similar to traditional importable classes, modules or libraries in languages like JavaScript, PHP, Python, Ruby, Java etc.

Graph currently has 25 plugins that are instantly available to your ADL development. Simply go to the "Plugins" section on your "Project" home page and add the ones you want. They'll, then, be immediately available for you to include in you ADL flows. Easy peasy.

 

{ }

Example Response

{}

Calling plugins

By default ADL will return all global variables as response if a eturn" element is not executed before the view completes. If the return element is found, whatever is defined in the data field will be returned as the response.

 

{ }
[{"paths":[],"data":{"uuid":"ab31fa63e7ca5a8b87c918faf3872869","plugin":"[\"Friends\",\"f8bd2277dd6e087f126d46d820909af5b5172a045855d14a164ff1d4\"]","args":{"id":"[email protected]"},"height":100,"step":"Get Luke's friends","data_to_var":"friends","action":"get|getFriends|friends","x":0,"y":0,"type":"plugin","width":160,"maxpaths":1}}]

Returning data

JSON returns

By default ADL will return all global variables as response if a "return" element is not executed before the view completes. If the return element is found, whatever is defined in the data field will be returned as the response.

 

{ }
[{"paths":[],"data":{"type":"return","step":"Return dict\/object with samples","maxpaths":0,"uuid":"f512613274c0e14f5e2bad1acbc5d275","height":32,"width":120,"x":0,"y":0,"data":"{\"list\/array\": [1, \"2\", false], \"int\": 10, \"bool\": true, \"string\": \"helloworld\", \"number\": 10.42}"}}]

Example Response

{"list\/array":[1,"2",false],"int":10,"bool":true,"string":"helloworld","number":10.42}

HTML returns

A killer feature of ADL on Graph is the ability to use a views as web application pages. Ala Django, Rails, and PHP, you can define logic and template HTML text to process at request time and return a web page instead of JSON data. To achieve this, all you need to do is set the header for the view before your view executes the return element.

 

{ }
[{"data":{"type":"library","step":"Set HTML headers","call":"internet.headers","args":{"headers":"{\"Content-Type\":\"text\/html\"}"},"data_to_var":"","maxpaths":1,"uuid":"9be399d311c4ea1bdc8cdcab1a70f9eb","x":0,"y":0,"width":120,"height":32,"internet":"internet","internet.headers":"headers"},"paths":["785230d79b05807d0ff5cb9ee413cf86"]},{"data":{"type":"return","step":"Return hello world HTML","maxpaths":0,"uuid":"785230d79b05807d0ff5cb9ee413cf86","x":0,"y":80,"width":120,"height":32,"data":"\n\thello world<\/body>\n<\/html>"},"paths":[]}]

Example Response

"\n\thello world<\/body>\n<\/html>"

Adding headers

Adding headers is a straightforward process in ADL. To achieve this, all you need to do is set the headers for the view before your view executes the return element. Provide the data as a dict/object and all headers provided will be set in the response.

 

{ }
[{"data":{"type":"library","step":"Set Plain Text headers","call":"internet.headers","args":{"headers":"{\"Content-Type\":\"text\/plain\"}"},"data_to_var":"","maxpaths":1,"uuid":"9be399d311c4ea1bdc8cdcab1a70f9eb","x":0,"y":0,"width":120,"height":32,"internet":"internet","internet.headers":"headers"},"paths":["785230d79b05807d0ff5cb9ee413cf86"]},{"data":{"type":"return","step":"Return hello world as 'text\/plain'","maxpaths":0,"uuid":"785230d79b05807d0ff5cb9ee413cf86","x":0,"y":80,"width":120,"height":32,"data":"hello world"},"paths":[]}]

Example Response

"\n\thello world<\/body>\n<\/html>"