{"id":15581913,"url":"https://github.com/fauna/js-sample-app","last_synced_at":"2025-10-23T15:05:19.646Z","repository":{"id":247866560,"uuid":"819503775","full_name":"fauna/js-sample-app","owner":"fauna","description":"Learn Fauna database fundamentals with Fauna Query Language (FQL) v10 and the JavaScript driver.","archived":false,"fork":false,"pushed_at":"2024-10-15T23:20:29.000Z","size":131,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":10,"default_branch":"main","last_synced_at":"2024-10-17T09:38:58.234Z","etag":null,"topics":["database-driver","fauna","javascript","nosql-databases","samples","serverless","typescript"],"latest_commit_sha":null,"homepage":"https://docs.fauna.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fauna.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-24T16:27:02.000Z","updated_at":"2024-10-15T23:20:31.000Z","dependencies_parsed_at":"2024-08-18T21:20:37.124Z","dependency_job_id":"83ae9ef6-f1ea-472a-851e-1f15aca88dbd","html_url":"https://github.com/fauna/js-sample-app","commit_stats":null,"previous_names":["fauna/js-sample-app"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fauna%2Fjs-sample-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fauna%2Fjs-sample-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fauna%2Fjs-sample-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fauna%2Fjs-sample-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fauna","download_url":"https://codeload.github.com/fauna/js-sample-app/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250760556,"owners_count":21482826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database-driver","fauna","javascript","nosql-databases","samples","serverless","typescript"],"created_at":"2024-10-02T20:00:21.331Z","updated_at":"2025-10-23T15:05:19.554Z","avatar_url":"https://github.com/fauna.png","language":"TypeScript","readme":"# Fauna JavaScript sample app\n\nThis sample app shows how to use [Fauna](https://fauna.com) in a production\napplication.\n\nThe app uses Node.js and the [Fauna v10 JavaScript\ndriver](https://github.com/fauna/fauna-js) to create HTTP API endpoints for an\ne-commerce store. You can use the app's API endpoints to manage products,\ncustomers, and orders for the store.\n\nThe app uses Fauna schemas and queries to:\n\n- Read and write data with strong consistency.\n\n- Define and handle relationships between resources, such as linking orders\n  to products and customers.\n\n- Validate data changes against business logic.\n\nThe app's source code includes comments that highlight Fauna best practices.\n\n\n## Highlights\n\nThe sample app uses the following Fauna features:\n\n- **[Document type\n  enforcement](https://docs.fauna.com/fauna/current/learn/schema/#type-enforcement):**\n  Collection schemas enforce a structure for the app's documents. Fauna rejects\n  document writes that don't conform to the schema, ensuring data consistency.\n  [Zero-downtime\n  migrations](https://docs.fauna.com/fauna/current/learn/schema/#schema-migrations)\n  let you safely change the schemas at any time.\n\n- **[Relationships](https://docs.fauna.com/fauna/current/learn/query/relationships/):**\n  Normalized references link documents across collections. The app's queries use\n  [projection](https://docs.fauna.com/fauna/current/reference/fql/projection/)\n  to dynamically retrieve linked documents, even when deeply nested. No complex\n  joins, aggregations, or duplication needed.\n\n- **[Computed\n  fields](https://docs.fauna.com/fauna/current/learn/schema/#computed-fields):**\n  Computed fields dynamically calculate their values at query time. For example,\n  each customer's `orders` field uses a query to fetch a set of filtered orders.\n  Similarly, each order's `total` is calculated at query time based on linked\n  product prices and quantity.\n\n- **[Constraints](https://docs.fauna.com/fauna/current/learn/schema/#unique-constraints):**\n  The app uses constraints to ensure field values are valid. For example, the\n  app uses unique constraints to ensure each customer has a unique email address\n  and each product has a unique name. Similarly, check constraints ensure each\n  customer has only one cart at a time and that product prices are not negative.\n\n- **[User-defined functions\n  (UDFs)](https://docs.fauna.com/fauna/current/learn/data-model/user-defined-functions/):**\n  The app uses UDFs to store business logic as reusable queries. For example,\n  the app uses a `checkout()` UDF to process order updates. `checkout()` calls\n  another UDF, `validateOrderStatusTransition()`, to validate `status`\n  transitions for orders.\n\n\n## Requirements\n\nTo run the app, you'll need:\n\n- A [Fauna account](https://dashboard.fauna.com/register). You can sign up for a\n  free account at https://dashboard.fauna.com/register.\n\n- [Node.js](https://nodejs.org/en/download/) v20.18 or later.\n  - [Node.js](https://nodejs.org/en/download/) v22 or later recommended.\n\n- [Fauna CLI v4](https://docs.fauna.com/fauna/current/build/cli/v4/).\n\n  To install the CLI, run:\n\n    ```sh\n    npm install -g fauna-shell\n    ```\n\n## Setup\n\n1. Clone the repo and navigate to the `js-sample-app` directory:\n\n    ```sh\n    git clone git@github.com:fauna/js-sample-app.git\n    cd js-sample-app\n    ```\n\n2. If you haven't already, log in to Fauna using the Fauna CLI:\n\n    ```sh\n    fauna login\n    ```\n\n3. Use the CLI to create the `ECommerce` database:\n\n    ```sh\n    # Replace 'us' with your preferred region group:\n    # 'us' (United States), 'eu' (Europe), or `global`.\n    fauna database create \\\n      --name ECommerce \\\n      --database us\n    ```\n\n4.  Push the `.fsl` files in the `schema`directory to the `ECommerce`\n    database:\n\n    ```sh\n    # Replace 'us' with your region group.\n    fauna schema push \\\n      --database us/ECommerce\n    ```\n\n    When prompted, accept and stage the schema.\n\n5.  Check the status of the staged schema:\n\n    ```sh\n    fauna schema status \\\n      --database us/ECommerce\n    ```\n\n6.  When the status is `ready`, commit the staged schema to the database:\n\n    ```sh\n    fauna schema commit \\\n      --database us/ECommerce\n    ```\n\n    The commit applies the staged schema to the database. The commit creates the\n    collections and user-defined functions (UDFs) defined in the `.fsl` files of the\n    `schema` directory.\n\n7. Create a key with the `server` role for the `ECommerce` database:\n\n    ```sh\n    fauna query \"Key.create({ role: 'server' })\" \\\n      --database us/ECommerce\n    ```\n\n    Copy the returned `secret`. The app can use the key's secret to authenticate\n    requests to the database.\n\n8. Make a copy of the `.env.example` file and name the copy `.env`. For example:\n\n    ```sh\n    cp .env.example .env\n    ```\n\n9.  In `.env`, set the `FAUNA_SECRET` environment variable to the secret you\n    copied earlier:\n\n    ```\n    ...\n    FAUNA_SECRET=fn...\n    ...\n    ```\n\n## Add sample data\n\nThe app includes tests that check the app's API endpoints and create related documents\nin the `ECommerce` database.\n\nFrom the root directory, run:\n\n```sh\nnpm install \u0026\u0026 npm run test\n```\n\nYou can view documents created by the tests in the [Fauna\nDashboard](https://dashboard.fauna.com/).\n\n\n## Run the app\n\nThe app runs an HTTP API server. From the root directory, run:\n\n```sh\nnpm install \u0026\u0026 npm run dev\n```\n\nOnce started, the local server is available at http://localhost:8000.\n\n\n## HTTP API endpoints\n\nThe app's HTTP API endpoints are defined in `*.controller.ts` files in the\n`src/routes` directory.\n\nReference documentation for the endpoints is available at\nhttps://fauna.github.io/js-sample-app/.\n\n\n### Make API requests\n\nYou can use the endpoints to make API requests that read and write data from\nthe `ECommerce` database.\n\nFor example, with the local server running in a separate terminal tab, run the\nfollowing curl request to the `POST /products` endpoint. The request creates a\n`Product` collection document in the `ECommerce` database.\n\n```sh\ncurl -v \\\n  http://localhost:8000/products \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"The Old Man and the Sea\",\n    \"price\": 899,\n    \"description\": \"A book by Ernest Hemingway\",\n    \"stock\": 10,\n    \"category\": \"books\"\n  }' | jq .\n```\n\n\n## Expand the app\n\nYou can further expand the app by adding fields and endpoints.\n\nAs an example, the following steps adds a computed `totalPurchaseAmt` field to\nCustomer documents and related API responses:\n\n1. If you haven't already, add the sample data:\n\n    ```sh\n    npm install \u0026\u0026 npm run test\n    ```\n\n2. In `schema/collections.fsl`, add the following `totalPurchaseAmt` computed\n  field definition to the `Customer` collection:\n\n    ```diff\n    collection Customer {\n      ...\n      // Use a computed field to get the set of Orders for a customer.\n      compute orders: Set\u003cOrder\u003e = (customer =\u003e Order.byCustomer(customer))\n\n    + // Use a computed field to calculate the customer's cumulative purchase total.\n    + // The field sums purchase `total` values from the customer's linked Order documents.\n    + compute totalPurchaseAmt: Number = (customer =\u003e customer.orders.fold(0, (sum, order) =\u003e {\n    +   let order: Any = order\n    +   sum + order.total\n    + }))\n      ...\n    }\n    ...\n    ```\n\n    Save `schema/collections.fsl`.\n\n3.  Push the updated schema to the `ECommerce` database:\n\n    ```sh\n    fauna schema push \\\n      --database us/ECommerce\n    ```\n\n    When prompted, accept and stage the schema.\n\n4.  Check the status of the staged schema:\n\n    ```sh\n    fauna schema status \\\n      --database us/ECommerce\n    ```\n\n5.  When the status is `ready`, commit the staged schema changes to the\n    database:\n\n    ```sh\n    fauna schema commit \\\n      --database us/ECommerce\n    ```\n\n6. In `src/routes/customers/customers.controller.ts`, add the\n   `totalPurchaseAmt` field to the `customerResponse` FQL template:\n\n    ```diff\n    // Project Customer document fields for consistent responses.\n    const customerResponse = fql`\n      customer {\n        id,\n        name,\n    +   email,\n    +   totalPurchaseAmt,\n        address\n      }\n    `;\n    ```\n\n    Save `src/routes/customers/customers.controller.ts`.\n\n    Customer-related endpoints use this template to project Customer\n    document fields in responses.\n\n7. Start the app server:\n\n    ```sh\n    npm install \u0026\u0026 npm run dev\n    ```\n\n8. With the local server running in a separate terminal tab, run the\n   following curl request to the `POST /customers` endpoint:\n\n    ```sh\n    curl -v http://localhost:8000/customers/999 | jq .\n    ```\n\n    The response includes the computed `totalPurchaseAmt` field:\n\n    ```json\n    {\n      \"id\": \"999\",\n      \"name\": \"Valued Customer\",\n      \"email\": \"valuedcustomer@fauna.com\",\n      \"totalPurchaseAmt\": 27000,\n      \"address\": {\n        \"street\": \"123 Main St\",\n        \"city\": \"San Francisco\",\n        \"state\": \"CA\",\n        \"postalCode\": \"12345\",\n        \"country\": \"United States\"\n      }\n    }\n    ```\n","funding_links":[],"categories":["Sample apps"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffauna%2Fjs-sample-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffauna%2Fjs-sample-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffauna%2Fjs-sample-app/lists"}