motia 0.11.0-beta.154 → 0.11.0-beta.155-562047
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/create/templates/nodejs/src/services/pet-store.ts.txt +29 -0
- package/dist/{esm/create/templates/nodejs/src/services/pet-store → cjs/create/templates/nodejs/src/services}/types.ts.txt +3 -2
- package/dist/cjs/create/templates/nodejs/steps/petstore/api.step.ts.txt +4 -5
- package/dist/cjs/create/templates/nodejs/steps/petstore/process-food-order.step.ts.txt +4 -3
- package/dist/cjs/create/templates/nodejs/steps/petstore/state-audit-cron.step.ts.txt +1 -9
- package/dist/cjs/create/templates/nodejs/tutorial/petstore/api.step.ts-features.json.txt +13 -30
- package/dist/cjs/create/templates/nodejs/tutorial/petstore/process-food-order.step.ts-features.json.txt +11 -28
- package/dist/cjs/create/templates/nodejs/tutorial/petstore/state-audit-cron.step.ts-features.json.txt +5 -11
- package/dist/cjs/create/templates/nodejs/tutorial/tutorial.tsx.txt +16 -22
- package/dist/cjs/create/templates/python/src/services/pet_store.py.txt +3 -3
- package/dist/cjs/create/templates/python/src/services/types.py.txt +3 -2
- package/dist/cjs/create/templates/python/steps/petstore/api_step.py.txt +2 -4
- package/dist/cjs/create/templates/python/steps/petstore/process_food_order_step.py.txt +2 -4
- package/dist/cjs/create/templates/python/tutorial/petstore/api_step.py-features.json.txt +9 -28
- package/dist/cjs/create/templates/python/tutorial/petstore/process_food_order_step.py-features.json.txt +9 -27
- package/dist/cjs/create/templates/python/tutorial/tutorial.tsx.txt +14 -20
- package/dist/esm/create/templates/nodejs/src/services/pet-store.ts.txt +29 -0
- package/dist/{cjs/create/templates/nodejs/src/services/pet-store → esm/create/templates/nodejs/src/services}/types.ts.txt +3 -2
- package/dist/esm/create/templates/nodejs/steps/petstore/api.step.ts.txt +4 -5
- package/dist/esm/create/templates/nodejs/steps/petstore/process-food-order.step.ts.txt +4 -3
- package/dist/esm/create/templates/nodejs/steps/petstore/state-audit-cron.step.ts.txt +1 -9
- package/dist/esm/create/templates/nodejs/tutorial/petstore/api.step.ts-features.json.txt +13 -30
- package/dist/esm/create/templates/nodejs/tutorial/petstore/process-food-order.step.ts-features.json.txt +11 -28
- package/dist/esm/create/templates/nodejs/tutorial/petstore/state-audit-cron.step.ts-features.json.txt +5 -11
- package/dist/esm/create/templates/nodejs/tutorial/tutorial.tsx.txt +16 -22
- package/dist/esm/create/templates/python/src/services/pet_store.py.txt +3 -3
- package/dist/esm/create/templates/python/src/services/types.py.txt +3 -2
- package/dist/esm/create/templates/python/steps/petstore/api_step.py.txt +2 -4
- package/dist/esm/create/templates/python/steps/petstore/process_food_order_step.py.txt +2 -4
- package/dist/esm/create/templates/python/tutorial/petstore/api_step.py-features.json.txt +9 -28
- package/dist/esm/create/templates/python/tutorial/petstore/process_food_order_step.py-features.json.txt +9 -27
- package/dist/esm/create/templates/python/tutorial/tutorial.tsx.txt +14 -20
- package/package.json +4 -4
- package/dist/cjs/create/templates/nodejs/src/services/pet-store/create-order.ts.txt +0 -15
- package/dist/cjs/create/templates/nodejs/src/services/pet-store/create-pet.ts.txt +0 -14
- package/dist/cjs/create/templates/nodejs/src/services/pet-store/index.ts.txt +0 -9
- package/dist/esm/create/templates/nodejs/src/services/pet-store/create-order.ts.txt +0 -15
- package/dist/esm/create/templates/nodejs/src/services/pet-store/create-pet.ts.txt +0 -14
- package/dist/esm/create/templates/nodejs/src/services/pet-store/index.ts.txt +0 -9
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Order, Pet } from './types'
|
|
2
|
+
|
|
3
|
+
export const petStoreService = {
|
|
4
|
+
createPet: async (pet: Omit<Pet, 'id'>): Promise<Pet> => {
|
|
5
|
+
const response = await fetch('https://xnigaj-xtnawg.motiahub.com/pet', {
|
|
6
|
+
method: 'POST',
|
|
7
|
+
body: JSON.stringify({
|
|
8
|
+
name: pet?.name ?? '',
|
|
9
|
+
photoUrls: [pet?.photoUrl ?? ''],
|
|
10
|
+
status: 'available',
|
|
11
|
+
}),
|
|
12
|
+
headers: { 'Content-Type': 'application/json' },
|
|
13
|
+
})
|
|
14
|
+
return response.json()
|
|
15
|
+
},
|
|
16
|
+
createOrder: async (order: Omit<Order, 'id' | 'complete'>): Promise<Order> => {
|
|
17
|
+
const response = await fetch('https://xnigaj-xtnawg.motiahub.com/store/order', {
|
|
18
|
+
method: 'POST',
|
|
19
|
+
body: JSON.stringify({
|
|
20
|
+
quantity: order?.quantity ?? 1,
|
|
21
|
+
petId: order?.petId ?? '1',
|
|
22
|
+
shipDate: order?.shipDate ?? new Date().toISOString(),
|
|
23
|
+
status: order?.status ?? 'placed',
|
|
24
|
+
}),
|
|
25
|
+
headers: { 'Content-Type': 'application/json' },
|
|
26
|
+
})
|
|
27
|
+
return response.json()
|
|
28
|
+
},
|
|
29
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
2
|
|
|
3
3
|
export const petSchema = z.object({
|
|
4
|
-
id: z.
|
|
4
|
+
id: z.string(),
|
|
5
5
|
name: z.string(),
|
|
6
6
|
photoUrl: z.string(),
|
|
7
7
|
})
|
|
@@ -11,9 +11,10 @@ export const orderStatusSchema = z.enum(['placed', 'approved', 'delivered'])
|
|
|
11
11
|
export const orderSchema = z.object({
|
|
12
12
|
id: z.string(),
|
|
13
13
|
quantity: z.number(),
|
|
14
|
-
petId: z.
|
|
14
|
+
petId: z.string(),
|
|
15
15
|
shipDate: z.string(),
|
|
16
16
|
status: orderStatusSchema,
|
|
17
|
+
complete: z.boolean(),
|
|
17
18
|
})
|
|
18
19
|
|
|
19
20
|
export type Pet = z.infer<typeof petSchema>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { ApiRouteConfig, Handlers } from 'motia'
|
|
2
2
|
import { z } from 'zod'
|
|
3
|
-
import { petStoreService
|
|
3
|
+
import { petStoreService } from '../../src/services/pet-store'
|
|
4
|
+
import { petSchema } from '../../src/services/types'
|
|
4
5
|
|
|
5
6
|
export const config: ApiRouteConfig = {
|
|
6
7
|
type: 'api',
|
|
7
8
|
name: 'ApiTrigger',
|
|
8
9
|
description: 'basic-tutorial api trigger',
|
|
9
10
|
flows: ['basic-tutorial'],
|
|
10
|
-
|
|
11
11
|
method: 'POST',
|
|
12
12
|
path: '/basic-tutorial',
|
|
13
13
|
bodySchema: z.object({
|
|
@@ -17,7 +17,6 @@ export const config: ApiRouteConfig = {
|
|
|
17
17
|
}),
|
|
18
18
|
foodOrder: z
|
|
19
19
|
.object({
|
|
20
|
-
id: z.string(),
|
|
21
20
|
quantity: z.number(),
|
|
22
21
|
})
|
|
23
22
|
.optional(),
|
|
@@ -29,7 +28,7 @@ export const config: ApiRouteConfig = {
|
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
export const handler: Handlers['ApiTrigger'] = async (req, { logger, traceId, emit }) => {
|
|
32
|
-
logger.info('Step 01
|
|
31
|
+
logger.info('Step 01 - Processing API Step', { body: req.body })
|
|
33
32
|
|
|
34
33
|
const { pet, foodOrder } = req.body
|
|
35
34
|
const newPetRecord = await petStoreService.createPet(pet)
|
|
@@ -38,7 +37,7 @@ export const handler: Handlers['ApiTrigger'] = async (req, { logger, traceId, em
|
|
|
38
37
|
await emit({
|
|
39
38
|
topic: 'process-food-order',
|
|
40
39
|
data: {
|
|
41
|
-
|
|
40
|
+
quantity: foodOrder.quantity,
|
|
42
41
|
email: 'test@test.com', // sample email
|
|
43
42
|
petId: newPetRecord.id,
|
|
44
43
|
},
|
|
@@ -10,15 +10,14 @@ export const config: EventConfig = {
|
|
|
10
10
|
subscribes: ['process-food-order'],
|
|
11
11
|
emits: ['notification'],
|
|
12
12
|
input: z.object({
|
|
13
|
-
id: z.string(),
|
|
14
13
|
email: z.string(),
|
|
15
14
|
quantity: z.number(),
|
|
16
|
-
petId: z.
|
|
15
|
+
petId: z.string(),
|
|
17
16
|
}),
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export const handler: Handlers['ProcessFoodOrder'] = async (input, { traceId, logger, state, emit }) => {
|
|
21
|
-
logger.info('Step 02
|
|
20
|
+
logger.info('Step 02 - Process food order', { input, traceId })
|
|
22
21
|
|
|
23
22
|
const order = await petStoreService.createOrder({
|
|
24
23
|
...input,
|
|
@@ -26,6 +25,8 @@ export const handler: Handlers['ProcessFoodOrder'] = async (input, { traceId, lo
|
|
|
26
25
|
status: 'placed',
|
|
27
26
|
})
|
|
28
27
|
|
|
28
|
+
logger.info('Order created', { order })
|
|
29
|
+
|
|
29
30
|
await state.set('orders', order.id, order)
|
|
30
31
|
|
|
31
32
|
await emit({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CronConfig, Handlers } from 'motia'
|
|
2
|
+
import { Order } from '../../src/services/types'
|
|
2
3
|
|
|
3
4
|
export const config: CronConfig = {
|
|
4
5
|
type: 'cron',
|
|
@@ -9,15 +10,6 @@ export const config: CronConfig = {
|
|
|
9
10
|
flows: ['basic-tutorial'],
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
type Order = {
|
|
13
|
-
id: number
|
|
14
|
-
petId: number
|
|
15
|
-
quantity: number
|
|
16
|
-
shipDate: string
|
|
17
|
-
status: string
|
|
18
|
-
complete: boolean
|
|
19
|
-
}
|
|
20
|
-
|
|
21
13
|
export const handler: Handlers['StateAuditJob'] = async ({ logger, state, emit }) => {
|
|
22
14
|
const stateValue = await state.getGroup<Order>('orders')
|
|
23
15
|
|
|
@@ -2,66 +2,49 @@
|
|
|
2
2
|
{
|
|
3
3
|
"id": "step-configuration",
|
|
4
4
|
"title": "Step Configuration",
|
|
5
|
-
"description": "All steps should have a defined configuration
|
|
6
|
-
"lines": [
|
|
7
|
-
"5-29"
|
|
8
|
-
]
|
|
5
|
+
"description": "All steps should have a defined configuration. This is how you define the step's behavior and how it will be triggered.",
|
|
6
|
+
"lines": ["6-28"]
|
|
9
7
|
},
|
|
10
8
|
{
|
|
11
9
|
"id": "api-configuration",
|
|
12
10
|
"title": "API Step",
|
|
13
11
|
"description": "Definition of an API endpoint",
|
|
14
|
-
"lines": [
|
|
15
|
-
"11-12"
|
|
16
|
-
]
|
|
12
|
+
"lines": ["7", "11-12"]
|
|
17
13
|
},
|
|
18
14
|
{
|
|
19
15
|
"id": "request-body",
|
|
20
16
|
"title": "Request body",
|
|
21
17
|
"description": "Definition of the expected request body. Motia will automatically generate types based on this schema.",
|
|
22
|
-
"lines": [
|
|
23
|
-
"13-24"
|
|
24
|
-
]
|
|
18
|
+
"lines": ["13-23"]
|
|
25
19
|
},
|
|
26
20
|
{
|
|
27
21
|
"id": "response-payload",
|
|
28
22
|
"title": "Response Payload",
|
|
29
|
-
"description": "Definition of the expected response payload
|
|
30
|
-
"lines": [
|
|
31
|
-
"25-27"
|
|
32
|
-
]
|
|
23
|
+
"description": "Definition of the expected response payload. Motia will generate the types automatically based on this schema. This is also important to create the Open API spec later.",
|
|
24
|
+
"lines": ["24-26"]
|
|
33
25
|
},
|
|
34
26
|
{
|
|
35
27
|
"id": "event-driven-architecture",
|
|
36
28
|
"title": "Emits",
|
|
37
|
-
"description": "We can define the events that this step will emit
|
|
38
|
-
"lines": [
|
|
39
|
-
"28",
|
|
40
|
-
"38-45"
|
|
41
|
-
]
|
|
29
|
+
"description": "We can define the events that this step will emit. This is how we can trigger other Motia steps.",
|
|
30
|
+
"lines": ["27", "37-44"]
|
|
42
31
|
},
|
|
43
32
|
{
|
|
44
33
|
"id": "handler",
|
|
45
34
|
"title": "Handler",
|
|
46
35
|
"description": "The handler is the function that will be executed when the step is triggered. This one receives the request body and emits events.",
|
|
47
|
-
"lines": [
|
|
48
|
-
"31-49"
|
|
49
|
-
]
|
|
36
|
+
"lines": ["30-48"]
|
|
50
37
|
},
|
|
51
38
|
{
|
|
52
39
|
"id": "logger",
|
|
53
40
|
"title": "Logger",
|
|
54
41
|
"description": "The logger is a utility that allows you to log messages to the console. It is available in the handler function. We encourage you to use it instead of console.log. It will automatically be tied to the trace id of the request.",
|
|
55
|
-
"lines": [
|
|
56
|
-
"32"
|
|
57
|
-
]
|
|
42
|
+
"lines": ["31"]
|
|
58
43
|
},
|
|
59
44
|
{
|
|
60
45
|
"id": "http-response",
|
|
61
46
|
"title": "HTTP Response",
|
|
62
|
-
"description": "The handler can return a response to the client.
|
|
63
|
-
"lines": [
|
|
64
|
-
"48"
|
|
65
|
-
]
|
|
47
|
+
"description": "The handler can return a response to the client. It must comply with the responseSchema defined in the step configuration.",
|
|
48
|
+
"lines": ["47"]
|
|
66
49
|
}
|
|
67
|
-
]
|
|
50
|
+
]
|
|
@@ -2,66 +2,49 @@
|
|
|
2
2
|
{
|
|
3
3
|
"id": "step-configuration",
|
|
4
4
|
"title": "Step Configuration",
|
|
5
|
-
"description": "All steps should have a defined configuration
|
|
6
|
-
"lines": [
|
|
7
|
-
"5-17"
|
|
8
|
-
]
|
|
5
|
+
"description": "All steps should have a defined configuration. This is how you define the step's behavior and how it will be triggered.",
|
|
6
|
+
"lines": ["5-17"]
|
|
9
7
|
},
|
|
10
8
|
{
|
|
11
9
|
"id": "event-configuration",
|
|
12
10
|
"title": "Event Step",
|
|
13
11
|
"description": "Definition of an event step that subscribes to specific topics",
|
|
14
|
-
"lines": [
|
|
15
|
-
"6",
|
|
16
|
-
"10-11"
|
|
17
|
-
]
|
|
12
|
+
"lines": ["6", "10"]
|
|
18
13
|
},
|
|
19
14
|
{
|
|
20
15
|
"id": "input-schema",
|
|
21
16
|
"title": "Input Schema",
|
|
22
17
|
"description": "Definition of the expected input data structure from the subscribed topic. Motia will automatically generate types based on this schema.",
|
|
23
|
-
"lines": [
|
|
24
|
-
"12-16"
|
|
25
|
-
]
|
|
18
|
+
"lines": ["12-16"]
|
|
26
19
|
},
|
|
27
20
|
{
|
|
28
21
|
"id": "event-emits",
|
|
29
22
|
"title": "Emits",
|
|
30
|
-
"description": "We can define the events that this step will emit, triggering other Motia
|
|
31
|
-
"lines": [
|
|
32
|
-
"11"
|
|
33
|
-
]
|
|
23
|
+
"description": "We can define the events that this step will emit, triggering other Motia steps.",
|
|
24
|
+
"lines": ["11"]
|
|
34
25
|
},
|
|
35
26
|
{
|
|
36
27
|
"id": "handler",
|
|
37
28
|
"title": "Handler",
|
|
38
29
|
"description": "The handler is the function that will be executed when the step receives an event from its subscribed topic. It processes the input data and can emit new events.",
|
|
39
|
-
"lines": [
|
|
40
|
-
"19-44"
|
|
41
|
-
]
|
|
30
|
+
"lines": ["19-46"]
|
|
42
31
|
},
|
|
43
32
|
{
|
|
44
33
|
"id": "state",
|
|
45
34
|
"title": "State Management",
|
|
46
35
|
"description": "The handler demonstrates state management by storing order data that can be accessed by other steps.",
|
|
47
|
-
"lines": [
|
|
48
|
-
"28"
|
|
49
|
-
]
|
|
36
|
+
"lines": ["30"]
|
|
50
37
|
},
|
|
51
38
|
{
|
|
52
39
|
"id": "event-emission",
|
|
53
40
|
"title": "Event Emission",
|
|
54
41
|
"description": "After processing the order, the handler emits a new event to notify other steps about the new order.",
|
|
55
|
-
"lines": [
|
|
56
|
-
"30-43"
|
|
57
|
-
]
|
|
42
|
+
"lines": ["32-45"]
|
|
58
43
|
},
|
|
59
44
|
{
|
|
60
45
|
"id": "logger",
|
|
61
46
|
"title": "Logger",
|
|
62
47
|
"description": "The logger is a utility that allows you to log messages to the console. It is available in the handler function and automatically ties to the trace id of the request.",
|
|
63
|
-
"lines": [
|
|
64
|
-
"20"
|
|
65
|
-
]
|
|
48
|
+
"lines": ["20", "28"]
|
|
66
49
|
}
|
|
67
|
-
]
|
|
50
|
+
]
|
|
@@ -2,25 +2,19 @@
|
|
|
2
2
|
{
|
|
3
3
|
"id": "step-configuration",
|
|
4
4
|
"title": "Step Configuration",
|
|
5
|
-
"description": "All steps should have a defined configuration
|
|
6
|
-
"lines": [
|
|
7
|
-
"3-10"
|
|
8
|
-
]
|
|
5
|
+
"description": "All steps should have a defined configuration. This is how you define the step's behavior and how it will be triggered.",
|
|
6
|
+
"lines": ["4-11"]
|
|
9
7
|
},
|
|
10
8
|
{
|
|
11
9
|
"id": "cron-configuration",
|
|
12
10
|
"title": "Cron Configuration",
|
|
13
11
|
"description": "Cron steps require a specific configuration structure with the 'type' field set to 'cron' and a valid cron expression.",
|
|
14
|
-
"lines": [
|
|
15
|
-
"4-5"
|
|
16
|
-
]
|
|
12
|
+
"lines": ["5-6"]
|
|
17
13
|
},
|
|
18
14
|
{
|
|
19
15
|
"id": "handler",
|
|
20
16
|
"title": "Cron Step Handler",
|
|
21
17
|
"description": "The Cron step handler only receives one argument.",
|
|
22
|
-
"lines": [
|
|
23
|
-
"21-51"
|
|
24
|
-
]
|
|
18
|
+
"lines": ["13-43"]
|
|
25
19
|
}
|
|
26
|
-
]
|
|
20
|
+
]
|
|
@@ -29,7 +29,7 @@ export const steps: TutorialStep[] = [
|
|
|
29
29
|
{
|
|
30
30
|
elementXpath: workbenchXPath.flows.node('apitrigger'),
|
|
31
31
|
title: 'API Step',
|
|
32
|
-
link: 'https://www.motia.dev/docs/concepts/steps#api
|
|
32
|
+
link: 'https://www.motia.dev/docs/concepts/steps#triggers-api',
|
|
33
33
|
description: () => (
|
|
34
34
|
<p>
|
|
35
35
|
Let's evaluate the Step that will allow you to receive traffic from external applications, API Steps will allow
|
|
@@ -156,7 +156,6 @@ export const steps: TutorialStep[] = [
|
|
|
156
156
|
object as the first argument, followed by a second argument that provides access to the <b>logger</b>,{' '}
|
|
157
157
|
<b>event emitter</b>, <b>state manager</b>, and <b>trace id</b>.<br />
|
|
158
158
|
<br />
|
|
159
|
-
<br />
|
|
160
159
|
💡 We will cover these in depth further down the tutorial.
|
|
161
160
|
</p>
|
|
162
161
|
),
|
|
@@ -188,10 +187,8 @@ export const steps: TutorialStep[] = [
|
|
|
188
187
|
<p>
|
|
189
188
|
Now let's wrap our API Step and return a response.
|
|
190
189
|
<br />
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
You simply need to return an object that complies with one of the <b>responseSchema</b> definitions
|
|
194
|
-
declared in your Step configuration.
|
|
190
|
+
You simply need to return an object that complies with one of the <b>responseSchema</b> definitions declared in
|
|
191
|
+
your Step configuration.
|
|
195
192
|
</p>
|
|
196
193
|
),
|
|
197
194
|
before: [{ type: 'click', selector: workbenchXPath.flows.feature('http-response') }],
|
|
@@ -202,7 +199,7 @@ export const steps: TutorialStep[] = [
|
|
|
202
199
|
{
|
|
203
200
|
elementXpath: workbenchXPath.flows.node('processfoodorder'),
|
|
204
201
|
title: 'Event Step',
|
|
205
|
-
link: 'https://www.motia.dev/docs/concepts/steps#event
|
|
202
|
+
link: 'https://www.motia.dev/docs/concepts/steps#triggers-event',
|
|
206
203
|
description: () => (
|
|
207
204
|
<p>
|
|
208
205
|
Now that we have an entry point in our flow, let's focus on subscribing to a <b>topic</b> and performing a
|
|
@@ -212,8 +209,8 @@ export const steps: TutorialStep[] = [
|
|
|
212
209
|
For this we will look at the <b>Event</b> Step.
|
|
213
210
|
<br />
|
|
214
211
|
<br />
|
|
215
|
-
<b> Event</b> Steps are essential for Motia's event driven architecture. Let's dive deeper into the
|
|
216
|
-
|
|
212
|
+
<b> Event</b> Steps are essential for Motia's event driven architecture. Let's dive deeper into the anatomy of
|
|
213
|
+
an Event Step by taking a look at the code visualization tool.
|
|
217
214
|
<br />
|
|
218
215
|
<br />
|
|
219
216
|
💡 <b>Event</b> Steps can only be triggered internally, through topic subscriptions.
|
|
@@ -224,7 +221,7 @@ export const steps: TutorialStep[] = [
|
|
|
224
221
|
{
|
|
225
222
|
elementXpath: workbenchXPath.sidebarContainer,
|
|
226
223
|
title: 'Event Step',
|
|
227
|
-
link: 'https://www.motia.dev/docs/concepts/steps#event
|
|
224
|
+
link: 'https://www.motia.dev/docs/concepts/steps#triggers-event',
|
|
228
225
|
description: () => (
|
|
229
226
|
<p>
|
|
230
227
|
Now that we have an entry point in our flow, let's focus on subscribing to a <b>topic</b> and performing a
|
|
@@ -232,8 +229,8 @@ export const steps: TutorialStep[] = [
|
|
|
232
229
|
<br /> <br />
|
|
233
230
|
For this we will look at the <b>Event</b> Step.
|
|
234
231
|
<br /> <br />
|
|
235
|
-
<b> Event</b> Steps are essential for Motia's event driven architecture. Let's dive deeper into the
|
|
236
|
-
|
|
232
|
+
<b> Event</b> Steps are essential for Motia's event driven architecture. Let's dive deeper into the anatomy of
|
|
233
|
+
an Event Step by taking a look at the code visualization tool.
|
|
237
234
|
<br /> <br />
|
|
238
235
|
💡 <b>Event</b> Steps can only be triggered internally, through topic subscriptions.
|
|
239
236
|
</p>
|
|
@@ -301,7 +298,7 @@ export const steps: TutorialStep[] = [
|
|
|
301
298
|
{
|
|
302
299
|
elementXpath: workbenchXPath.flows.node('stateauditjob'),
|
|
303
300
|
title: 'Cron Step',
|
|
304
|
-
link: 'https://www.motia.dev/docs/concepts/steps#cron
|
|
301
|
+
link: 'https://www.motia.dev/docs/concepts/steps#triggers-cron',
|
|
305
302
|
description: () => (
|
|
306
303
|
<p>
|
|
307
304
|
Let's do a recap of what you've learned, thus far you've become familiar with two Step types <b>API</b>{' '}
|
|
@@ -317,7 +314,7 @@ export const steps: TutorialStep[] = [
|
|
|
317
314
|
{
|
|
318
315
|
elementXpath: workbenchXPath.sidebarContainer,
|
|
319
316
|
title: 'Cron Schedule',
|
|
320
|
-
link: 'https://www.motia.dev/docs/concepts/steps#cron
|
|
317
|
+
link: 'https://www.motia.dev/docs/concepts/steps#triggers-cron',
|
|
321
318
|
description: () => (
|
|
322
319
|
<p>
|
|
323
320
|
<b>CRON</b> Steps are similar to the other Step types, they are composed by a configuration and a handler.
|
|
@@ -353,7 +350,7 @@ export const steps: TutorialStep[] = [
|
|
|
353
350
|
before: [{ type: 'click', selector: workbenchXPath.flows.feature('handler') }],
|
|
354
351
|
},
|
|
355
352
|
|
|
356
|
-
//
|
|
353
|
+
// Endpoints
|
|
357
354
|
|
|
358
355
|
{
|
|
359
356
|
elementXpath: workbenchXPath.links.endpoints,
|
|
@@ -397,7 +394,7 @@ export const steps: TutorialStep[] = [
|
|
|
397
394
|
description: () => (
|
|
398
395
|
<p>
|
|
399
396
|
Once you click on an endpoint from the list, you will be able to test it by providing a request payload and
|
|
400
|
-
clicking on the <b>
|
|
397
|
+
clicking on the <b>Send</b> button.
|
|
401
398
|
<br />
|
|
402
399
|
<br />
|
|
403
400
|
This section will provide an overview of your API endpoint.
|
|
@@ -437,16 +434,13 @@ export const steps: TutorialStep[] = [
|
|
|
437
434
|
This form will allow you to validate your API Step by executing an HTTP request against your API endpoint.
|
|
438
435
|
</p>
|
|
439
436
|
<br />
|
|
440
|
-
<br />
|
|
441
437
|
<p>You can also test your API endpoints using your terminal through the curl command.</p>
|
|
442
438
|
<br />
|
|
443
|
-
<br />
|
|
444
439
|
<p>
|
|
445
440
|
💡 Thanks to the <b>bodySchema</b> attribute from the API Step config, you are automatically provided with a
|
|
446
441
|
sample request payload.
|
|
447
442
|
</p>
|
|
448
443
|
<br />
|
|
449
|
-
<br />
|
|
450
444
|
<pre className="code-preview">
|
|
451
445
|
<code className="language-bash">
|
|
452
446
|
curl -X POST http://localhost:3000/basic-tutorial \<br />
|
|
@@ -454,7 +448,7 @@ export const steps: TutorialStep[] = [
|
|
|
454
448
|
{' '}-d '
|
|
455
449
|
{JSON.stringify({
|
|
456
450
|
pet: { name: 'Jack', photoUrl: 'https://images.dog.ceo/breeds/pug/n02110958_13560.jpg' },
|
|
457
|
-
foodOrder: {
|
|
451
|
+
foodOrder: { quantity: 1 },
|
|
458
452
|
})}
|
|
459
453
|
'
|
|
460
454
|
</code>
|
|
@@ -471,7 +465,7 @@ export const steps: TutorialStep[] = [
|
|
|
471
465
|
title: 'API Endpoint Test',
|
|
472
466
|
description: () => (
|
|
473
467
|
<p>
|
|
474
|
-
Once you've filled the request payload, you can click on the <b>
|
|
468
|
+
Once you've filled the request payload, you can click on the <b>Send</b> button to trigger an HTTP request
|
|
475
469
|
against your API endpoint.
|
|
476
470
|
</p>
|
|
477
471
|
),
|
|
@@ -480,7 +474,7 @@ export const steps: TutorialStep[] = [
|
|
|
480
474
|
type: 'fill-editor',
|
|
481
475
|
content: {
|
|
482
476
|
pet: { name: 'Jack', photoUrl: 'https://images.dog.ceo/breeds/pug/n02110958_13560.jpg' },
|
|
483
|
-
foodOrder: {
|
|
477
|
+
foodOrder: { quantity: 1 },
|
|
484
478
|
},
|
|
485
479
|
},
|
|
486
480
|
],
|
|
@@ -12,7 +12,7 @@ class PetStoreService:
|
|
|
12
12
|
|
|
13
13
|
async with httpx.AsyncClient() as client:
|
|
14
14
|
response = await client.post(
|
|
15
|
-
'https://
|
|
15
|
+
'https://xnigaj-xtnawg.motiahub.com/pet',
|
|
16
16
|
json=pet_data,
|
|
17
17
|
headers={'Content-Type': 'application/json'}
|
|
18
18
|
)
|
|
@@ -22,13 +22,13 @@ class PetStoreService:
|
|
|
22
22
|
async with httpx.AsyncClient() as client:
|
|
23
23
|
order_data = {
|
|
24
24
|
"quantity": order.get("quantity", 1),
|
|
25
|
-
"petId": 1,
|
|
25
|
+
"petId": order.get("pet_id", '1'),
|
|
26
26
|
"shipDate": order.get("ship_date", "2025-08-22T22:07:04.730Z"),
|
|
27
27
|
"status": order.get("status", "placed"),
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
response = await client.post(
|
|
31
|
-
'https://
|
|
31
|
+
'https://xnigaj-xtnawg.motiahub.com/store/order',
|
|
32
32
|
json=order_data,
|
|
33
33
|
headers={'Content-Type': 'application/json'}
|
|
34
34
|
)
|
|
@@ -7,13 +7,14 @@ class OrderStatus(str, Enum):
|
|
|
7
7
|
DELIVERED = "delivered"
|
|
8
8
|
|
|
9
9
|
class Pet(BaseModel):
|
|
10
|
-
id:
|
|
10
|
+
id: str
|
|
11
11
|
name: str
|
|
12
12
|
photoUrl: str
|
|
13
13
|
|
|
14
14
|
class Order(BaseModel):
|
|
15
15
|
id: str
|
|
16
16
|
quantity: int
|
|
17
|
-
petId:
|
|
17
|
+
petId: str
|
|
18
18
|
shipDate: str
|
|
19
19
|
status: OrderStatus
|
|
20
|
+
complete: bool
|
|
@@ -8,7 +8,6 @@ class PetRequest(BaseModel):
|
|
|
8
8
|
photoUrl: str
|
|
9
9
|
|
|
10
10
|
class FoodOrder(BaseModel):
|
|
11
|
-
id: str
|
|
12
11
|
quantity: int
|
|
13
12
|
|
|
14
13
|
class RequestBody(BaseModel):
|
|
@@ -31,7 +30,7 @@ config = {
|
|
|
31
30
|
|
|
32
31
|
async def handler(req, context):
|
|
33
32
|
body = req.get("body", {})
|
|
34
|
-
context.logger.info("Step 01
|
|
33
|
+
context.logger.info("Step 01 - Processing API Step", {"body": body})
|
|
35
34
|
|
|
36
35
|
pet = body.get("pet", {})
|
|
37
36
|
food_order = body.get("foodOrder", {})
|
|
@@ -42,11 +41,10 @@ async def handler(req, context):
|
|
|
42
41
|
await context.emit({
|
|
43
42
|
"topic": "process-food-order",
|
|
44
43
|
"data": {
|
|
45
|
-
"id": food_order.get("id"),
|
|
46
44
|
"quantity": food_order.get("quantity"),
|
|
47
45
|
"email": "test@test.com", # sample email
|
|
48
46
|
"pet_id": new_pet_record.get("id"),
|
|
49
47
|
},
|
|
50
48
|
})
|
|
51
49
|
|
|
52
|
-
return {"status": 200, "body": {**new_pet_record, "traceId": context.trace_id}}
|
|
50
|
+
return {"status": 200, "body": {**new_pet_record, "traceId": context.trace_id}}
|
|
@@ -3,10 +3,9 @@ from datetime import datetime
|
|
|
3
3
|
from src.services.pet_store import pet_store_service
|
|
4
4
|
|
|
5
5
|
class InputSchema(BaseModel):
|
|
6
|
-
id: str
|
|
7
6
|
email: str
|
|
8
7
|
quantity: int
|
|
9
|
-
pet_id:
|
|
8
|
+
pet_id: str
|
|
10
9
|
|
|
11
10
|
config = {
|
|
12
11
|
"type": "event",
|
|
@@ -19,10 +18,9 @@ config = {
|
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
async def handler(input_data, context):
|
|
22
|
-
context.logger.info("Step 02
|
|
21
|
+
context.logger.info("Step 02 - Process food order", {"input": input_data, "traceId": context.trace_id})
|
|
23
22
|
|
|
24
23
|
order = await pet_store_service.create_order({
|
|
25
|
-
"id": input_data.get("id"),
|
|
26
24
|
"quantity": input_data.get("quantity"),
|
|
27
25
|
"pet_id": input_data.get("pet_id"),
|
|
28
26
|
"email": input_data.get("email"),
|
|
@@ -3,67 +3,48 @@
|
|
|
3
3
|
"id": "step-configuration",
|
|
4
4
|
"title": "Step Configuration",
|
|
5
5
|
"description": "All steps should have a defined configuration, this is how you define the step's behavior and how it will be triggered.",
|
|
6
|
-
"lines": [
|
|
7
|
-
"6-30"
|
|
8
|
-
]
|
|
6
|
+
"lines": ["6-29"]
|
|
9
7
|
},
|
|
10
8
|
{
|
|
11
9
|
"id": "api-configuration",
|
|
12
10
|
"title": "API Step",
|
|
13
11
|
"description": "Definition of an API endpoint",
|
|
14
|
-
"lines": [
|
|
15
|
-
"23-24"
|
|
16
|
-
]
|
|
12
|
+
"lines": ["18", "22-23"]
|
|
17
13
|
},
|
|
18
14
|
{
|
|
19
15
|
"id": "request-body",
|
|
20
16
|
"title": "Request body",
|
|
21
17
|
"description": "Definition of the expected request body. Motia will automatically generate types based on this schema.",
|
|
22
|
-
"lines": [
|
|
23
|
-
"6-16",
|
|
24
|
-
"25"
|
|
25
|
-
]
|
|
18
|
+
"lines": ["6-15", "24"]
|
|
26
19
|
},
|
|
27
20
|
{
|
|
28
21
|
"id": "response-payload",
|
|
29
22
|
"title": "Response Payload",
|
|
30
23
|
"description": "Definition of the expected response payload, Motia will generate the types automatically based on this schema. This is also important to create the Open API spec later.",
|
|
31
|
-
"lines": [
|
|
32
|
-
"4",
|
|
33
|
-
"26-28"
|
|
34
|
-
]
|
|
24
|
+
"lines": ["4", "25-27"]
|
|
35
25
|
},
|
|
36
26
|
{
|
|
37
27
|
"id": "event-driven-architecture",
|
|
38
28
|
"title": "Emits",
|
|
39
29
|
"description": "We can define the events that this step will emit, this is how we can trigger other Motia Steps.",
|
|
40
|
-
"lines": [
|
|
41
|
-
"29",
|
|
42
|
-
"42-50"
|
|
43
|
-
]
|
|
30
|
+
"lines": ["28", "41-48"]
|
|
44
31
|
},
|
|
45
32
|
{
|
|
46
33
|
"id": "handler",
|
|
47
34
|
"title": "Handler",
|
|
48
35
|
"description": "The handler is the function that will be executed when the step is triggered. This one receives the request body and emits events.",
|
|
49
|
-
"lines": [
|
|
50
|
-
"32-52"
|
|
51
|
-
]
|
|
36
|
+
"lines": ["31-50"]
|
|
52
37
|
},
|
|
53
38
|
{
|
|
54
39
|
"id": "logger",
|
|
55
40
|
"title": "Logger",
|
|
56
41
|
"description": "The logger is a utility that allows you to log messages to the console. It is available in the handler function. We encourage you to use it instead of console.log. It will automatically be tied to the trace id of the request.",
|
|
57
|
-
"lines": [
|
|
58
|
-
"34"
|
|
59
|
-
]
|
|
42
|
+
"lines": ["33"]
|
|
60
43
|
},
|
|
61
44
|
{
|
|
62
45
|
"id": "http-response",
|
|
63
46
|
"title": "HTTP Response",
|
|
64
47
|
"description": "The handler can return a response to the client. This is how we can return a response to the client. It must comply with the responseSchema defined in the step configuration.",
|
|
65
|
-
"lines": [
|
|
66
|
-
"52"
|
|
67
|
-
]
|
|
48
|
+
"lines": ["50"]
|
|
68
49
|
}
|
|
69
|
-
]
|
|
50
|
+
]
|