Have you looked at the moderated blog example?
It has lists similar to your project: Posts
and Users
, that can be Contributors
or Moderators
. The contributor/moderator distinction doesn't matter much in your case, the part you'll be interested in are the hooks on the Post
list, specifically the resolveInput.create
hook, which looks like this:
hooks: {
resolveInput: {
create: ({ context, resolvedData }) => {
resolvedData.createdAt = new Date();
if (context.session?.contributor) {
return {
...resolvedData,
createdBy: {
connect: {
id: context.session?.contributor?.id,
},
},
};
}
return resolvedData;
},
},
// Other hooks...
},
As per the docs:
The resolveInput
function is used to modify or augment the data values passed in to a create
or update
operation.
So this is our chance to change values before they're saved, including populating or enforcing values like your Post.author
field.
resolveInput
gets the context
object, which includes a reference to the session
object. The contents of this object is determine by your session store functions but usually contains info about the current user. In this example, if the user signed in is a contributor, we get their contributor Id from context.session?.contributor?.id
and save it to the createdBy
field. The createdAt
field is also set to the current date and time.
Note that, because this hook is configured at the list level, data for the whole item should be returned (basically, the resolvedData
object with any additional changes the hook wants to make). Another way to do this would be to add resolvedData
functions at the field level but then we'd need two separate functions - one for createdAt
and another for createdBy
– each of which would return a single value. See the hooks guide for more on this distinction.
Also, its important not to conflate hooks with access control – ie. whether a contributor should be allowed to create a post in the first place. In this example access control is configured separately, up in the list access
config, as it should be.
One final note – at the time of writing the hook API docs cover the resolveInput
hook (at the list and field levels), but don't break it down into the different operations (ie. resolveInput.create
and resolveInput.update
). This is just a recent syntactic improvement, it doesn't change anything fundamental about how hooks are to be used. If using just the documented API, the code above could be written as:
hooks: {
resolveInput: ({ operation, context, resolvedData }) => {
// Only run for create operations (so ignore updates)
if (operation !== 'create') return resolvedData;
resolvedData.createdAt = new Date();
if (context.session?.contributor) {
return {
...resolvedData,
createdBy: {
connect: {
id: context.session?.contributor?.id,
},
},
};
}
return resolvedData;
},
// Other hooks...
},