Back

Why are there multiple variables for "payloads" in Functions?

  • 0
  • Functions
  • Web
skavank
19 Jul, 2023, 07:55

Why not always use the same payload structure, to streamline execution, and not confuse new users by referencing things in the Docs that don't fully correlate to the variable names? πŸ™‚

TL;DR
The user is questioning the use of multiple variables for payloads in Functions and requesting clarification on why event data is separate from execution data. They provide their journey as a new user and express frustration with the inconsistency in the documentation. The user suggests using a unified payload structure and provides an example code for handling payload based on the trigger type. They ask for the reasoning behind the current approach and suggest making it clearer in the documentation. Solution: The support team acknowledges the feedback and informs the user that in the next version of Functions, data will only be in 'req.body'. They appreciate the feedback and assure the user that it has been passed on to
skavank
19 Jul, 2023, 07:58

Is there a reason why the payload data for executions could not be stored in the same variable as the payload data for an event?

skavank
19 Jul, 2023, 08:04
TypeScript
module.exports = (req, res) => {
  const maybePayload = req.payload;
  const maybeAlsoPayload = req.variables.APPWRITE_FUNCTION_EVENT_DATA
  const trigger = req.variables.APPWRITE_FUNCTION_TRIGGER;

  let actualPayload;

  if (trigger === 'http') {
    actualPayload = maybePayload;
  }
  if (trigger === 'event') {
    actualPayload = maybeAlsoPayload
  }

  // do things with payload
}
skavank
19 Jul, 2023, 08:06

Unnecessary boilerplate imho πŸ‘† - unless there is some technical limitation to having all payloads normalized.

Just seems a bit odd to me that the variable is stored in different names. The main confusion was about the docs mentioning "payload" for all events, and then req.payload being empty when called from an event. You understand I'm sure.

D5
19 Jul, 2023, 08:17

Supposedly when you're triggering an execution you will not need payload

D5
19 Jul, 2023, 08:17

The payload functionality is to send data from a client to a function (as you might know)

D5
19 Jul, 2023, 08:20

So if you're scheduling execution, the data sent to it through payload is not going to change, consequently it's practically useless, since for static data you have env variables

skavank
19 Jul, 2023, 11:05

I know all this. I understand how it all works! I'm just questioning, or rather asking for, the reasoning behind doubling up on the variable inputs, and/or trying to make a case for making this clearer in the documentation.

skavank
19 Jul, 2023, 11:06

It's because I know how it works that I'm questioning it.

skavank
19 Jul, 2023, 11:08

You can see why it would make sense, especially when testing Functions, to be able to trigger a Function <:functions:1108648038156746792> made to respond to events, but using an execution with a payload (for testing, or various other reasons).

skavank
19 Jul, 2023, 11:10

But in order to do that we have to consider that the payload can be in multiple places.

skavank
19 Jul, 2023, 11:18

I might add this to my toolkit.

TypeScript
const { getPayload, getClient, CollectionHelper} = require('x')

module.exports = (req, res) => {
  const payload = getPayload(req) // normalize payload entry, and return json
  const client = getClient(req) // build a client from req.variables
  const databases = new Databases(client)

  const userId = req.variables.APPWRITE_FUNCTION_USER_ID;

  // forwards CRUD operations so we don't have to define which database and collection each time
  const messages = new CollectionHelper(databases, 'chat', 'messages')   

  if (payload.owner !== userId) {
    messages.update(payload.$id, { owner: userId })
  }

  res.json({success: true})
}
Drake
19 Jul, 2023, 15:50

good question...I would assume it's to make it clear that req.variables.APPWRITE_FUNCTION_EVENT_DATA is data that came from an event and req.payload is input payload. I'll ask the team for additional insight, though

Drake
19 Jul, 2023, 15:53

referencing things in the Docs that don't fully correlate to the variable names

What do you mean?

Drake
19 Jul, 2023, 16:21

The main confusion was about the docs mentioning "payload" for all events

Can you provide more details about this? I found 1 reference in the function variables docs (https://appwrite.io/docs/functions#functionVariables). Where else?

skavank
19 Jul, 2023, 18:03

This was my journey as someone who has not touched Appwrite before:

  • Okay, let's make Function to solve users impersonating others by providing false ids
  • I'm gonna need to trigger this Function on a CREATE or UPDATE Event that checks if the User set someone else's ID on a document
  • I'll go to the Events documentation to figure our how this is done https://appwrite.io/docs/events
  • I can see the name of the event, and the payload of the event, great
  • I set up a new function: appwrite init function
  • Oh nice, it even mentions req.payload right there in the file, neat!
  • Deploy the function
  • Why is my payload empty when the event is triggered?
  • Try to execute the function manually
  • Wait, now my payload is not empty? Is something wrong with the event?
  • Read https://appwrite.io/docs/client/functions, just mentions that Functions run in response to events, or executions
  • Go to https://appwrite.io/docs/events again, did I miss anything? Just mentions payloads and event names... then why is my payload empty?
  • Okay, let's check the guide https://appwrite.io/docs/functions, the example is right there, mentions req.payload... then why is my event payload empty?
  • Keep reading, look at the https://appwrite.io/docs/functions#execute. "besides events you can also manually execute", yes I tried that, my payload is empty on events tho?
  • Keep reading, scheduled execution, abuse and limits, ignored files, supported runtimes... hmm
  • Get to "Function variables", finally reach the APPWRITE_FUNCTION_EVENT_DATA, wait, it's not payload? Why is it not payload.
skavank
19 Jul, 2023, 18:09

It could just be that the words get mixed up. Payload is of course a generic term, and it is the right word, in the context where there is a variable literally named "payload" however mixups can happen. There is no mention, nor explanation for why event data is separate from execution data. I don't see why it would be. This is nitpicky, it just caused me some frustation, and I'm sure I'm not the only one who goes through the same.

Drake
19 Jul, 2023, 18:35

interesting...thanks for the detailed insight! <:appwritepeepo:902865250427215882>

Drake
19 Jul, 2023, 18:36

ya..."payload" is generic and we use it in multiple places, including realtime πŸ‘€

skavank
19 Jul, 2023, 18:57

It's all good, sorry if I'm being shouty, I'm just nitpicking - Appwrite is great

Drake
19 Jul, 2023, 19:00

no worries! this is really great feedback! i've passed it along to the team so we can discuss this and how to improve

Drake
19 Jul, 2023, 19:48

ok so in the next version of functions, we won't have the data in multiple places. it'll only be in req.body. hopefully that will be simple/clear enough.

D5
19 Jul, 2023, 20:53

req.body? What's that? πŸ˜…

D5
19 Jul, 2023, 20:53

Isn't req.data?

Meldiron
20 Jul, 2023, 07:10

In next version we focus on making functions follow HTTP standards. So on request you will have stuff like body, headers, url, method... If I am not mistaken, all that was considered payload until now will go into request body. So no matter if manual execution, event, or anything else.. Incoming data will always be in req.body

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more