# Conductor Tutorial: Build and Publish a REST Application This tutorial uses a ready-made two-page project to introduce Conductor's main features. You will import it, run REST actions, inspect bindings, modify the visual design, save it, and publish it as a standalone application. Allow about 25 minutes. You need an administrator account because project authoring and publishing are administrator functions. ## What you will build The companion [Post Workshop project](../examples/project-definitions/valid-conductor-tutorial.json) uses the public JSONPlaceholder training API. It contains: - two pages with automatic navigation and button navigation; - Labels, Text Input, Text Area, Buttons, Status Panel, Table, and JSON Viewer components; - a global typed variable; - GET and POST REST actions; - component and variable request templates; - a page `onLoad` action and Button `onClick` actions; - action-response bindings and a Table-selection binding; and - public-publishing-compatible anonymous actions. JSONPlaceholder simulates writes but does not save them. Do not enter private, confidential, or production information; tutorial field values are sent to a public third-party service. Its behavior is documented in the [JSONPlaceholder guide](https://jsonplaceholder.typicode.com/guide/). ## 1. Import the project 1. Download or open `examples/project-definitions/valid-conductor-tutorial.json` from the Conductor source bundle. 2. Sign in to Conductor as an administrator. 3. Open **JSON Editor**. 4. Select all existing JSON and replace it with the complete contents of `valid-conductor-tutorial.json`. 5. Select **Apply**. 6. Confirm the validation summary reports no errors, then open **Visual Editor**. Applying JSON changes the in-memory project; it does not save it to the database. If Apply fails, confirm you copied the entire file and that `schemaVersion` remains `0.1.0`. ## 2. Tour the Visual Editor The **Create a Post** page should be selected. Notice these parts of the workspace: - The project command area shows the project name and New, Save, Load, and Preview controls. - The page ribbon switches pages and changes page names, slugs, order, navigation visibility, and lifecycle events. - The component palette adds controls to the active page. - The canvas shows the application layout. - **Selection** edits the selected component's identity, position, size, properties, appearance, and events. Select **Post title**, **Post body**, **Create post**, and **API response** in turn. Observe how Text Input, Text Area, Button, and JSON Viewer expose different properties. Try one harmless visual change: 1. Select the heading. 2. Change its displayed text to `My REST Post Workshop`. 3. Move or resize it on the canvas. The dot beside the project name indicates an unsaved canonical change. ## 3. Run the POST action 1. Open **Preview**. 2. Change the post title and body if desired, using only non-sensitive tutorial text. 3. Select **Create post**. The Status Panel should show created ID `101`, and the JSON Viewer should display the simulated response. This single interaction demonstrates: ```text Button onClick → Create simulated post action → component and variable template interpolation → server-side POST request → response bindings → Status Panel and JSON Viewer runtime updates ``` Return to **JSON Editor** and notice that your Preview inputs, response, and ID were not written into the project. Preview state is intentionally ephemeral. ## 4. Inspect the action and templates Open **Actions & Bindings**, expand **REST Actions**, and open **Create simulated post**. The action sends `POST https://jsonplaceholder.typicode.com/posts` with a JSON content type. Its request body uses these values: ```text {{components.postTitle.value}} {{components.postBody.value}} {{variables.defaultUserId}} ``` Component values come from the page that invoked the action. `defaultUserId` is a global number variable with default value `1`. Use **Test Action** only to understand its limitation: action testing has no interactive Preview component state. Template-driven actions should be exercised from Preview, where the components have runtime values. ## 5. Inspect the response bindings In **Actions & Bindings**, expand **Response Bindings**. The POST action has two `onSuccess` bindings: | Source | Target | Result | |---|---|---| | `actions.action_create_post.response.body.id` | `components.createdPostId.value` | Shows the returned ID in the Status Panel. | | `actions.action_create_post.response.body` | `components.createResponse.value` | Shows the complete body in the JSON Viewer. | Bindings move response data into runtime component properties. They do not modify authored defaults or save API responses in project JSON. ## 6. Explore pages, page events, and tables 1. Return to **Preview**. 2. Select **Browse sample posts** or use the automatic page navigation. 3. Wait for the table to populate. 4. Select any table row. Opening **Browse Posts** for the first time triggers its page `onLoad` event, which runs **Load sample posts**. Its response body is bound to `components.postsTable.rows`. Selecting a row triggers a different kind of binding: ```text components.postsTable.selectedRow → components.selectedPost.value → onChange ``` The JSON Viewer displays the selected record without making another REST request. Select **Refresh posts** to run the GET action explicitly, then use **Back to create** to exercise button-based page navigation. ## 7. Change a variable Open **Actions & Bindings**, expand **Variables**, and inspect `defaultUserId`. This global number is used by both actions: - the POST body assigns the simulated post to that user; and - the GET query filters the table by that user. Change its default from `1` to `2`, return to Preview, and reload or re-enter the Browse page. The table should now show posts for user 2. This illustrates how one declared value can drive several request fields. ## 8. Add a component Return to **Visual Editor** and add one component of your choice. For example: 1. Select the **Create a Post** page. 2. Add a **Checkbox**. 3. Name it `reviewedTutorial`. 4. Set its label to `I reviewed this tutorial`. 5. Move it beneath the navigation button. Preview the application and interact with it. The checkbox value exists only during that loaded Preview session unless you deliberately use it in a request template. ## 9. See validation protect the project 1. Open **JSON Editor**. 2. Find the Create post Button's `actionId` value: `action_create_post`. 3. Temporarily change it to `missing_action`. 4. Select **Apply**. Conductor should report a semantic reference error and preserve the last valid project. Correct the value or select **Revert**. This is the same validation gate used by Apply, Save, Update, Load, and Publish. ## 10. Save and reload 1. Return to **Visual Editor**. 2. Select **Save**. 3. If prompted, keep the name `Conductor Tutorial — Post Workshop` or choose a unique tutorial name. 4. Make another small edit and select **Update**. 5. Select **New**, confirm the discard prompt only if no unsaved work remains, then select **Load** and reopen the tutorial project. The authored pages, components, actions, bindings, and variable should return. Preview-only values and API responses should not. ## 11. Review history Open **Execution History**. The GET and POST attempts should appear with method, sanitized URL, outcome, duration, status, size, and a bounded response preview. History is for troubleshooting. It does not store request or response headers, cookies, credentials, or sensitive query values. Use **Clear history** only when you intentionally want to remove all retained execution records. ## 12. Publish the application Because both tutorial actions use anonymous authentication, the project can be published publicly. 1. Confirm the project is saved and valid. 2. Open **Publishing**. 3. Select the tutorial project. 4. Enter a display name and a unique slug such as `post-workshop`. 5. Choose **Public** or **Restricted to users**. 6. Select **Publish**, then **Open app**. 7. Test both pages and refresh the `/apps//browse-posts` deep link directly. Saving the source project does not update the live snapshot. Make a visible source edit, save it, and use **Republish** to learn that lifecycle. **Unpublish** removes public access without deleting the source project. ## 13. Where credentials fit This tutorial deliberately uses anonymous actions. For a real protected API: 1. An administrator creates an encrypted credential under **Actions & Bindings → Secrets**. 2. The action selects its authentication type and the compatible opaque secret reference. 3. Conductor injects the credential server-side; it never places the value in project JSON or the published browser application. Public applications cannot contain credential-backed actions. Choose restricted visibility for such an application. Never paste credentials into URLs, headers, templates, tutorial data, or JSON. ## Next steps - Use the [User Guide](USER_GUIDE.md) as the feature reference. - Use the [Project Schema](SCHEMA.md) when editing JSON directly. - Use the [Administrator Guide](ADMIN_GUIDE.md) for accounts, credentials, publishing, and security boundaries. - Use [Troubleshooting](TROUBLESHOOTING.md) if a request or published route fails.