Creating Token FQL10

Beginner Question: How to Reference a Document in FQL10?

Context:

I’m currently building a TypeScript wrapper around Fauna’s FQL10 and learning the new syntax as I go. I’ve written some functions that generate FQL, and I want to ensure they are producing the correct output.

Here’s a sample of what I’m working on:

import type { TokenConfig } from '../../schema/config/model';
import { createToken } from './createToken';

describe('createToken', () => {
  let config: TokenConfig;

  beforeEach(() => {
    config = { document: 'doc1' };
  });

  it('generates correct output with no secret, ttl, and data', () => {
    expect(createToken(config)).toEqual(`
Token.create({
  document: "doc1"
});
`);
  });

  it('generates correct output for token with all details', () => {
    config.secret = 'secret';
    config.ttl = new Date().getTime();
    config.data = { desc: 'hello world' };
    
    expect(createToken(config)).toEqual(`
Token.create({
  document: "doc1",
  secret: secret,
  ttl: ${config.ttl},
  data: {
    desc: "hello world"
  }
});
`);
  });
});

Issue:

When I test the output string in the Fauna web shell console, I’m encountering type-check errors related to the document field.

I read through the Fauna documentation on Token.create, but I’m still unclear on how to properly reference a document.

I understand what a document is, but I’m unsure how to reference one in my FQL. For example, I have a collection called accounts. How do I tell FQL that I want to reference a specific document in that collection, such as an Account?

Any help would be greatly appreciated!

I found my the answer, sort of. I can simply use the collection name as is, for example.

I suppose I was thinking of how to define an alias for accounts collection such as Account.

Token.create({
  document: accounts.byId("372696914650464289")
})

Hi @AndrewRedican Glad to see you able to move forward!

To expand on your answer, I want to highlight that using .byId is not the only way to acquire a document for storing relationships. Whether it’s a relationship in your own documents, or in a native document like a Token, you can also use indexes or otherwise search for the document.

let account = accounts.byEmail("paul@example.com").first()! // use '!' to error if no result found

Token.create({ document: account })

See also our page on relationships in general. I’ll pass this on to our docs team, too. I wonder if it would be valuable to discuss more about Document values on the Tokens.create() page.

Thanks for the additional information @ptpaterson ; it’s really helpful. I didn’t occur to me there were other expressions available besides .byId() that could be used to reference a document.

It would also be useful to clarify the different ways a document can be referenced, just to give a better understanding of what’s possible.

I have a question: is a token limited to a single document, or can it be assigned to a list of documents? I don’t have a specific or immediate use case for assigning a token to multiple documents or to the result of a function returning a list of documents—I’m just curious about what options the API provides. It might be handy. If that is not a thing; then would referencing other documents from within the main document for which the token is created for would be another way to “bundle” or “package” some data for it to be accessed later.

Additionally, it would be great to see a few different “recipes” or examples for achieving similar outcomes within the context of this API. For instance, beyond .byId(), what other expressions are available?

For example, in a collection that defines X columns, is it always the case that once a collection is defined, the type-check system is extended with additional expressions? If we have a collection like “lenders” with a field called legalTaxId, does that automatically enable expressions like lender.byLegalTaxId(''), and so on?

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.

Different patterns with Tokens

You could, for example, have a Group collection that has relationships to individuals. Tokens can be associated with any user document, so you could generate tokens specific to that group, or you associate tokens with the individual and define ABAC rules that check for such relationships.

You can use Credentials assigned to documents, too, rather than create Tokens directly. Fauna automatically hashes passwords before storing them. https://docs.fauna.com/fauna/current/learn/security/tokens/#create-manage-tokens

Field definitions

You might check out our language reference docs. Here’s where we discuss the dot syntax specifically. Field accessors and method chaining - Fauna Docs

Adding a field definitions does not add methods to your documents. It simply adds extra information and validation about the shape of data in your documents.

The default schema for a collection is essentially { * any }, so you can write and read any field you want to a document. For example you could write and read a legalTaxId field out of the box. Adding a field definition, such as legalTaxId: String to your collection definition means that you now require all documents to have that field and that it must be of type String. Nothing about access has changed, you still use .legalTaxId.

Indexes

Index calls are associated with the static module in FQL that represents your collection. If your collection is named Lender and it has an index that you define called byLegalTaxId, then you can call it in FQL like Lender.byLegalTaxId(...).

1 Like