As the name implies, in a Joystick app, a setter is a way to "set" data on/to a data source. Typically that data source is a database, but it could also be a third-party API, a static file, etc. Ultimately, a setter is nothing more than a function being called with some helpful utilities and context added.
Setters are HTTP POST Routes
While they may not look like it syntactically, behind the scenes, setters are registered as HTTP POST routes via Express (following the pattern /api/_setters/<setter_name>
).
It's recommended that setters are organized in your /api
folder, in sub-directories with names related to the data being modified. For example, if we had a collection/table in our database called books
, we'd want to define a folder like /api/books
. Inside of that folder, we'd create a file for our setters at /api/books/setters.js
, exporting an object from that file with all of our book-related setter definitions.
Example Usage
Defining a Setter
Following the above example, let's define a setter for adding some books to our database.
api/books/setters.js
import joystick from '@joystick.js/node';
const setters = {
create_book: {
set: () => {
return process.databases.mongodb.collection('books').insertOne({
_id: joystick.id(),
title: 'Example Book',
author: 'Example Author',
});
}
}
};
export default setters;
Above, we've defined a simple setter create_book
. To do it, we assign create_book
as a key on a parent object containing all of our book-related setters. To that key, we've assigned another object with a single method set()
: the function on our setter that's responsible for writing data.
In this example, we're calling to our database and inserting an example book.
Random ID Generation
To keep document/row IDs consistent in your database, it's recommended that you use Joystick's built-in joystick.id()
method to generate IDs. IDs are generated by default as 16-character alphanumerical strings, but can have their length set by passing an integer
value to the function like joystick.id(32)
.
Accessing Input and Context
When a setter is called (typically via the set()
method imported from @joystick.js/ui
or the api.set()
method passed to a component's data function), input
can be passed along with the request containing the data to insert, update, or use for determining what to update.
api/books/setters.js
import joystick from '@joystick.js/node';
const setters = {
create_book: {
set: (input = {}) => {
return process.databases.mongodb.collection('books').insertOne({
_id: joystick.id(),
title: input?.title,
author: input?.author,
category: input?.category,
});
}
}
};
export default setters;
If there's any input
passed with a setter request, Joystick will pass it as the first argument to your set()
function. Above, we anticipate a title
, author
, and category
being passed in the input
and utilize it in our database insert.
api/books/setters.js
const setters = {
create_book: {
set: (input = {}, context = {}) => {
return process.databases.mongodb.collection('books').insertOne({
_id: joystick.id(),
title: input?.title,
author: input?.author,
category: input?.category,
owner: context?.user?._id,
});
}
}
};
export default setters;
In addition to input
, as the second argument to your setter's set()
function, a context
object is passed with a few different sub-fields:
req
– The inbound HTTP request related to the setter request.user
– If available, the currently logged-in user.<database_provider>
– A connection to the database driver for one of your app's configured database providers (e.g.,context.mongodb
orcontext.postgresql
).
Above, as an example, we've referenced the currently logged-in user's _id
field (if our user's database provider was a SQL database like PostgreSQL, we'd reference context.user.user_id
) on the context
object.
API
Definition
set(input: object, context: object) => any;
Parameters
- input object
- If passed from the client, the input value for the setter request. Defaults to an empty object if nothing is passed.
- context object
- The context object automatically passed by Joystick containing the inbound HTTP request, user object (if available), and database provider connections (e.g., context.mongodb or context.postgresql).