Getting Started

Installing MobQL

You can install MobQL from your preferred package manager

npm install mobql --save

# or

yarn add mobql

Setting up MobQL

There's three steps to get set up, preparing your data loader, defining your objects, and registering your objects.

Step 1 - Preparing your data loader

Your data loader is what MobQL uses to send the requests to your GraphQL endpoint. This means MobQL can be used with any GraphQL client you want or even no client at all.

src/dataLoader.ts
class MyDataLoader extends DataLoader {
  async runQuery(query: string, variables: any): Promise<any> {
    let output;
    try {
      /*
       * In here you can add things like authentication, etc.
       * all it needs to do is make a request with the given
       * query and variables
       */
      output = await request(
        "https://countries.trevorblades.com/graphql",
        query,
        variables
      );
    } catch (e) {
      // Log your errors, send them to Sentry, etc.
    }
    /* 
     * Make sure that your runQuery function puts the data in the 
     * data property of the return value, in the future other 
     * properties will be used for other data
     */
    return { data: output };
  }
}

Step 2 - Defining your objects

Now it's time to model our data. The bread and butter of MobQL is the DataLoadedList, and is what you'll probably be using most often in your time with MobQL. A DataLoadedList represents a set of one type of Object, this could be users, posts, comments, documents, etc.

There's a only a couple things you need to do to define a basic list object. First you need to define all its properties. Then you need to setup the constructor and getId(), these allow MobQL to pass the id of the object in when it's initialized by the ObjectManager and also allows the MobQL to grab the id at any time.

class ExampleObject extends DataLoadedListEntry {
    id: string;
    prop1: number | null = null;
    prop2: string | null = null;
    
    constructor(id: string, manager: DataLodedListEntryManager<any>) {
        super(manager);
        this.id = id;
    }
    
    getId() {
        return this.id;
    }
}

There's a second type of object you may want to define while you're getting set up, the DataLoadedObject. A DataLoadedObject represents something that a client may only ever see one of, for instance a global settings object, or an @me query, or any sort of global data passed to the application.

These are a bit quicker to define, just extend DataLoadedObject and define the properties.

class ExampleGlobalObject extends DataLoadedObject {
    prop1: number | null = null;
    prop2: string | null = null;
}

You might have noticed in the last couple examples that all the properties have a | null in their type and are initialized to null. This is a limitation of the current implementation as the initializer wont be able to check all the properties and create the handlers necessary to load them if they aren't initialized with a value other than undefined.

Step 3 - Registering your Objects

The last step to getting set up is creating your ObjectManager and registering your objects. The ObjectManager is the brains of MobQL, it keeps track of all your objects and acts as your object store.

Start by creating a new ObjectManager and passing it your DataLoader.

const store = new ObjectManager(dataLoader);

Then register your types.

store.registerListType(ExampleObject, "example");
store.registerObject(ExampleGlobalObject, "settings");

This will register your types and get them ready for use. Behind the scenes this will put the types in your store so that they can be referenced by other objects when hydrating queries, this will also set up the lists for your DataLoadedListEntrys.

You're ready to go!

You now have MobQL set up, to use it just pass your store to your app just like you would in MobX and set up your components as observers so that they update as soon as the data changes. If you don't know how to do this, you can reference MobX's docs here. You can pull objects from your store like this:

const obj = store.getList(ExampleObject).get("id");
const settings = store.getObject(ExampleGlobalObject);

Where do I go from here?

These docs are still a work in progress while I finalize the API and learn more about potential uses that I may need to design extra features for. I'll keep working on these docs as I iron out the wrinkles and finalize parts of the API. For now you can take a look at the source code and the examples in the repo to see what you can do.

Last updated