This demo app showcases a simple integration with an Nhost backend. In this demo:
- Upload and remove files
- Sign in a new or existing user
- Create, read, update and delete data with GraphQL
- Display preview images using server-side image transformations
Recommended node version is 14 LTS or 16 LTS.
# Install dependencies
npm install
# Start project locally
npm run serve
# Start project locally
# Connects to the development backend running on localhost
npm run serve:local
# Build static app
npm run build
# Lint and test
npm run lint
npm run test
npm run test:watch
vue.config.js
defines some parts of the build process that impact the app. See Vue CLI configuration reference for more details. You can also override environment variables locally by adding an .env.local
file to the project.
This app interacts with a backend on Nhost. This repo includes the backend setup that can be run either locally or on nhost.io.
First, go to GitHub and fork this repository.
Then, sign up for free on nhost.io. Once you're logged in, create a new App on any region of your choice.
After creating the app, press Connect to GitHub, and pick your fork of this repository. Nhost will then deploy this app.
Add the backend URL as an environment variable (VUE_APP_NHOST_BACKEND_URL
) or edit src/config.js
to connect to your new backend.
To run the backend in a local development environment:
The CLI will start the development environment and show you where it's running. Add this backend URL as an environment variable (VUE_APP_NHOST_BACKEND_URL
) or edit src/config.js
to connect to your new backend.
If you want to set things up manually, or just understand how the setup process is done, follow these steps after creating a new Nhost app:
This app uses passwordless login, which is enabled for new apps by default. You shouldn't have to change any settings for a new app on Nhost.
Authentication methods can be found under Users → Login settings.
First, add a new table called uploads
into the public
schema. Add the following fields:
- Frequently used columns:
id
(UUID) andcreated_at
(timestamp) - A new field called
owner_user_id
(UUID)
Then, define relationships:
- From
files
touploads
- Go to
files
table - Under "Modify"
- Add a column
upload_id
(UUID, NULLABLE) - Add a foreign key to
public.uploads
(upload_id
→id
)
- Add a column
- Under "Relationships", add the suggested Object relationship to
uploads
- Also go and add the reverse relationships in
uploads
(array)
- Go to
- From
uploads
tousers
- Go to
uploads
table - Under "Modify"
- You should see the column
owner_user_id
(UUID) - Add a foreign key to
auth.users
(owner_user_id
→id
) - Under "Relationships", add the suggested Object relationship to
users
- You should see the column
- Also go and add the reverse relationships in
users
(array)
- Go to
All authenticated requests will be made with the role user
. You have to add it when editing permissions for the first time.
In the users
table:
- I want to query my own data. For
user
role'sselect
permission:- Row select permissions:
{"id":{"_eq":"X-Hasura-User-Id"}}
- Column select permissions: "Toggle all"
- Row select permissions:
In uploads
table:
- I want to create new
upload
objects, if I'm authenticated and my user exists. Addinsert
permission:- Row insert permissions: "Without any checks"
- Column insert permissions: "Toggle all"
- I want to read
uploads
whose owner is me. Addselect
permission- Row select permissions:
{"owner_user_id":{"_eq":"X-Hasura-User-Id"}}
- Column select permissions: "Toggle all"
- Row select permissions:
- I want to change the owner of
uploads
whose current owner is me. Addupdate
permission- Row update permissions: "Same as select"
- Column update permissions:
owner_user_id
- I want remove
uploads
whose owner is me. Adddelete
permission- Row remove permissions: "Same as select, pre update"
In files
table:
- I want to upload files if I have an account and am logged in. Add
insert
permission:- Row insert permissions: "Without any checks"
- Column insert permissions: "Toggle all"
- I want to read files that are in
uploads
whose owner is me. Addselect
permission:- Row select permissions:
{"_or":[{"upload":{"owner_user_id":{"_eq":"X-Hasura-User-Id"}}},{"uploaded_by_user_id":{"_eq":"X-Hasura-User-Id"}}]}
- Column select permissions: "Toggle all"
- Row select permissions:
- I want to update the
upload_id
of files. Addupdate
permission:- Row update permissions: "Same as select"
- Column update permissions:
upload_id
- I want to remove files. Add
delete
permission:- Row remove permissions: "Same as select, pre update"
We also want files to have viewable link, but not let them be queryable without authorisation. This can be achieved using the public
role:
- Go to
files
and "Permissions" - Add a new role called
public
, and add theseselect
permissions- Row select permissions: "Without any checks"
- Limit number of rows to
0
- Column select permissions: "Toggle all"
If we upload a file, we want the backend to automatically create a reference to the user who uploaded the file. We need to tell Hasura to do this, it's not enabled by default.
- Go to the
files
table - Select "permissions"
- Select the
user
role'sinsert
permissions - Scroll down and click "Column presets"
- Select
uploaded_by_user_id
→ from session variable →X-Hasura-User-Id
It's common to trigger behavior whenever an object is created or deleted, for example. In this app, we want to write an entry into a logs
table every time an Upload
is created. This can be achieved using Events and Functions.
First, let's create a place for our logs:
- Create a table called
logs
(underpublic
) with the following columns:id
(UUID, primary key)message
(String)user_id
(UUID, nullable)data
(JSONB, nullable)
- Create "Foreign key":
- From
user_id
→auth.users.id
- From
- Create relationship:
- Add the suggested object relationship (
logs.user_id
→users.id
)
- Add the suggested object relationship (
Since we will write logs
as an admin, we don't need to set any permissions.
We must first create an event trigger. In Hasura Console, go to "Events":
- Click on Create
- Trigger name: "onUploadsInsert"
- Database table:
default
→public.uploads
- Trigger opetation: On table
insert
- Webhook URL:
{{NHOST_BACKEND_URL}}/v1/functions/triggers/onUploadsInsert
- Under "Advanced", add a header:
- Key:
nhost-webhook-secret
- Value: change
Value
to 'From env var` - Enter
NHOST_WEBHOOK_SECRET
- Key:
- Click "Create Event Trigger"
Now, after the event has been created, Hasura will send a POST request to the URL you defined. Because we have the corresponding function in this repository, it will have been deployed to that URL to receive that request.
You can see how functions/triggers/onUploadsInsert.js
looks like to understand what's happening.