Common-SenseMakers / sensemakers

Sensemakers infrastructure for developing AI-based tools for semantic annotations of social posts. Cross-poster app to publish your semantic posts on different networks.
GNU General Public License v3.0
1 stars 2 forks source link

[APP] Consider Modular API in the backend too #28

Open pepoospina opened 5 months ago

pepoospina commented 5 months ago

Check this docs and explore if the repositories can use the Modular API. If they do, then consider moving the users and posts repositories into the frontend @shared folder. Then they can be used by both the FE and BE.

weswalla commented 5 months ago

It's not clear to me why we need to switch to the web modular API. From what I can tell, the main reason is to reduce bundle size due to "tree-shaking": https://stackoverflow.com/questions/73802297/what-is-going-on-with-new-googles-web-9-modular-syntax-vs-previous-web-8name

(which seems like something we will want to do, for performance reasons)

Regarding subscribing to real-time updates to the firestore database directly in the client, this should be possible with either version of the API: https://firebase.google.com/docs/firestore/query-data/listen

The main consideration seems to be in how we handle either firebase-admin or firebase modules respectively. In our server-side code, we use firebase-admin to instantiate the connection with firestore, but if we wanted to share the same repository classes on the client-side, it would need to use the firebase module to restrict its privileges. (note: there is a similar upgrade process for firebase-admin: https://firebase.google.com/docs/admin/migrate-node-v10)

an example of what this might look like:

export class DBInstance {
  protected firestore: Firestore;

  public collections: {
    signup: FirebaseFirestore.CollectionReference<FirebaseFirestore.DocumentData>;
    users: FirebaseFirestore.CollectionReference<FirebaseFirestore.DocumentData>;
    posts: FirebaseFirestore.CollectionReference<FirebaseFirestore.DocumentData>;
  };

  // pass firestore to the constructor that way it can either come from `firebase-admin` or `firebase`
  constructor(firestore: Firestore) {
    this.collections = {
      signup: this.firestore.collection(CollectionNames.Signup),
      users: this.firestore.collection(CollectionNames.Users),
      posts: this.firestore.collection(CollectionNames.Posts),
    };
  }

  get batch() {
    return this.firestore.batch();
  }
}

// client-side example
import { getFirestore } from 'firebase-admin/app';
new DBInstance(getFirestore())

// server-side example
import { getFirestore } from 'firebase/firestore';
new DBInstance(getFirestore())
pepoospina commented 5 months ago

The main motivation was to be able to reuse the same code (the repository services) on the frontend and the backend. Both have equivalent functionalities but the Modular API is more modern and clean, in my experience.