Skip to content

Apollo server data source wrapping Firestore REST APIs

Notifications You must be signed in to change notification settings

devskope/apollo-firesource

Repository files navigation

Apollo-Firesource

Apollo server datasource wrapping Firestore REST APIs.    [PRs welcome 😊]

Basic Usage

  • Set required environment variables:

    • FIRESOURCE_CREDENTIALS=<Path-to-service-account-json> // must have firestore access
  • Pass FireSource instance as option to ApolloServer constructor:

    const server = new ApolloServer({
      typeDefs,
      resolvers,
      dataSources: () => {
        return {
          firestore: new FireSource({
            projectId: <Firestore-project-id>
            // ... other options
          }),
        };
      },
    });
  • Access the data source from resolvers:

    Query: {
      document: async (parent, args, ctx) => {
        const { documentPath } = args;
        const { dataSources: { firestore } } = ctx;
    
        try {
          // get document by id from collection
          return firestore.documents().get({ documentPath });
        } catch (error) {
          /* handle error
           *
           * Ideally first handle Firestore error responses:
           *   error.extensions?.response - exception details
           *
           * Then FireSource Errors:
           *   error.extensions.code === <'BAD_USER_INPUT'|'UNAUTHENTICATED'>
           *   error.message - exception details
           */
        }
      },
    },

    API

    Constructor - firestore = new FireStore(config):

    • config (object):
      {
        projectId: string, // (required) Firestore project ID
        version: 'v1', // string (optional)
        resource: 'databases', // string: <'databases' | 'locations'> (optional)
        database: '(default)', // string (optional)
      }

    Documents - firestore.documents()

    • presets

      • documentBasePath = projects/<Firestore-project-id>/databases/<database>/documents Paths relative to documentBasePath (collectionPath/documentPath) must start with and not end with '/'   ex: '/users/bob'
    • methods (async):

      • batchGet(options) => batchGetResult

        Get multiple documents from database.

        • options (object)

          {
            documents: string[], // (required) Array of document paths relative to documentBasePath ('.../databases/<db>/documents')  ex '/users/mike1'
            fieldsToReturn: string[], // (optional) array of document fields to include in response
          
            // (optional)
            consistencySelector: {
              // Union field consistencySelector can be only one of the following:
              transaction: string,  // Reads documents in a transaction: A base64-encoded string.
              newTransaction: TransactionOptions, // https://cloud.google.com/firestore/docs/reference/rest/v1/TransactionOptions
              readTime: string
            }
          }
        • returns (object): BatchGetResult

          {
            documents: Array,
            documentCount:number,
            missing: Array,
            readTime: string,
            transaction: string
          }

      • beginTransaction(options) => object

        Start a new transaction.

        • options (object): optional

          // https://cloud.google.com/firestore/docs/reference/rest/v1/TransactionOptions
          {
            readOnly: {
              readTime: string // (optional): Timestamp format
            },
            readWrite: {
              retryTransaction: string // (optional)
            }
          
          }
        • returns (object):

          {
            transaction: string;
          }

      • create(options) => Document

        Insert new document into a collection.

        • options (object)

          {
            collectionPath: string, // (required) path to parent collection relative to documentBasePath
            docId: string   // (optional) custom document id
            fieldsToReturn: string[] // (optional) array of fields to include in response (mask)
            data: {
              name: string  // (optional) document resource name
              fields: {
                "fieldName": {
                  // where 'valueType' is one of https://cloud.google.com/firestore/docs/reference/rest/v1/Value
                  valueType: value
                }
              }
            }
          }
        • returns (object): Document

          {
            name: string
            fields: object,
            createTime: string,
            updateTime: string,
          }

      • commit(options) => CommitResponse

        Commits a transaction while optionally updating documents.

        • options (object)

          {
            transaction: string, // (required) A base64-encoded transaction id string.
          
            // writes is an array of objects
            writes: [
              {
                // (required)  The operation to execute
                operation: {
                  // Union field operation can be only one of the following:
                  delete: string,   // Path to document to delete relative to documentBasePath,  ex. '/users/joe'
                  transform: {
                    documentPath: string,  // (required) Path to document relative to documentBasePath
                    fieldTransforms: Array<fieldTransform> // (required) Array of field transforms to apply;
                  }
                  update: {
                    documentPath: string,  // (required) Path to document to update relative to documentBasePath
                    fields: {
                      fieldName: {
                        // where 'valueType' is one of https://cloud.google.com/firestore/docs/reference/rest/v1/Value
                        valueType: value
                      }
                    },
                  };
                }
          
                // (optional)
                currentDocument: {
                  // Union field currentDocument can be only one of the following:
                  exists: boolean,   // (optional) When set to true, the target document must exist. When set to false, the target document must not exist
                  updateTime: string // (optional) Timestamp format When set, the target document must exist and have been last updated at that time
                }
          
                // (optional) Can be set only when the operation is update. if not set, existing document is overitten
                updateOptions: {
                  // Union field updateOptions can be only one of the following:
                  updateAll: boolean,  // (optional) update all fields
                  fieldsToUpdate: string[], // array of fields to update
                }
              }
            ]
          }
        • fieldTransform (object)

          {
            fieldPath: string; // (required) Path of field to transform
            transformType: {
              // Union field transformType can be only one of the following:
              setToServerValue: 'SERVER_VALUE_UNSPECIFIED' | 'REQUEST_TIME'; // Sets the field to the given server value.
              increment: object; // Adds the given value to the field's current value.
              maximum: object; // Sets the field to the maximum of its current value and the given value.
              minimum: object; // Sets the field to the minimum of its current value and the given value.
              appendMissingElements: object; // Append the given elements in order if they are not already present in the current field value
              removeAllFromArray: object; //  Remove all of the given elements from the array in the field.
            }
          }
        • returns (object): CommitResponse

          {
            writeResults: Array; // https://cloud.google.com/firestore/docs/reference/rest/v1/WriteResult
            commitTime: string;
          }

      • delete(options) => object

        Delete document from collection.

        • options (object)

          {
            documentPath: string, // (required) path to document relative to documentBasePath
          
            // (optional)
            currentDocument: {
              exists: boolean,  // (optional) When set to true, the target document must exist. When set to false, the target document must not exist
              updateTime: string // (optional) Timestamp format: When set, the target document must exist and have been last updated at that time
            }
          }
        • returns (object):

          {
            deleted: boolean;
          }

      • get(options) => DocumentData | DocumentData[]

        Retrieve one or all documents from a collection.

        • options (object)

          {
            collectionPath: string,  // (optional) relative path to collection: if set and !documentPath ,get all documents in collection
            documentPath: string,    // (optional) relative path to document: if set and !collectionPath, get single document
            fieldsToReturn: string[]   // (optional) Array of fields to include in response (mask)
          }
        • returns (object): Document | Documents

          // Document
          {
            name: string
            fields: object,
            createTime: string,
            updateTime: string,
          }
          
          // Documents
          {
            documents: Document[];
            documentCount: number;
          }

      • list(options) => ListResult

        Get a list of documents

        • options (object)

          {
            collectionPath: string;    // (required) Full collection path relative to documentPath ex: '/users'
            fieldsToReturn: string[];  // (optional) array of fields to include in response (mask)
          
            // (optional)
            queryOptions: {
              pageSize: number,      // (optional) Maximum number of documents to return
              pageToken: string,     // (optional) The nextPageToken value returned from a previous List request, if any.
              showMissing: boolean,  // (optional)  Show missing documents. Requests with showMissing may not specify orderBy.
              orderBy: string,       // (optional) The order to sort results by. For example: priority desc, name.
          
              // (optional)
              consistencySelector: {
                // can be only one of the following:
                transaction: string,   // (optional) Reads documents in a transaction: A base64-encoded string
                readTime: string     // (optional) string (Timestamp format): Reads documents as they were at the given time
              }
            }
          }
        • returns (object): ListResult

          {
            documents: Array,
            documentCount:number,
            nextPageToken: string  // The next page token.
          }

      • listCollectionIds(options) => ListCollectionIdsResult

        List IDs of collections that are children of given document

        • options (object)

          {
            documentPath: string;   // (required) Full path of parent document with child collection ids to list ex: '/chatrooms/roomx'
            pageSize: number,       // (optional) Maximum number of ids to return
            pageToken: string,     // (optional) The nextPageToken value returned from a previous listCollectionIds request, if any.
          }
        • returns (object): ListCollectionIdsResult

          {
            collectionIds: string[],
            idCount: number,
            nextPageToken: string  // The next page token.
          }

      • rollBack(options) => RollbackResult

        Roll back a transaction.

        • options (object)

          {
            transaction: string; // (required) Transaction to rollback A base64-encoded string
          }
        • returns (object): RollbackResult

          {
            rolledBack: true;
          }

      • runQuery(options) => queryResult

        Run a query against the database.

        • options (object)

          {
            structuredQuery: object, // (required) https://cloud.google.com/firestore/docs/reference/rest/v1/StructuredQuery
            documentPath: string,  // (optional)  path relative to documentBasePath
          
            // (optional)
            consistencySelector: {
              // can be only one of the following:
              transaction: string, // Reads documents in a transaction: A base64-encoded string
              newTransaction: TransactionOptions, // https://cloud.google.com/firestore/docs/reference/rest/v1/TransactionOptions
              readTime: string
            }
          }
        • returns (object): QueryResult

          {
            documents: Array,
            documentCount:number,
            readTime: string,
            skippedResults: number,
            transaction: string
          }

      • update(options) => Document

        Update document in collection by id.

        • options (object)

          {
            documentPath: string,  // (required)  document path relative to documentBasePath
            fieldsToReturn: string[], // (optional) array of fields to include in response (mask)
            data: {
              name: string, // (optional) document resource name
              fields: {
                "fieldName": {
                  // where 'valueType' is one of https://cloud.google.com/firestore/docs/reference/rest/v1/Value
                  valueType: value
                }
              }
            },
            updateOptions: {
              updateAll: boolean, // (optional) update all fields
              fieldsToUpdate: string[], // (optional, required if !updateAll) array of fields to update
          
              // (optional)
              currentDocument: {
                exists: boolean, // (optional) When set to true, the target document must exist. When set to false, the target document must not exist
                updateTime: string // (optional) Timestamp format When set, the target document must exist and have been last updated at that time
              }
            }
          }
        • returns (object): The updated document


About

Apollo server data source wrapping Firestore REST APIs

Resources

Stars

Watchers

Forks

Packages

No packages published