Global app state with single data point

What is the best way to store global state data for an application. Right now I have a State Type, and I only create one of this object which I read/update as needed. If a second was created for whatever reason it would totally break things.

I want to store the state in Slash GraphQL. Right now the State is just simply one field, but more things may be added later.

Is there a better way than just creating a type and pre-creating the initial row of it to later read/update as needed. Is there a way to enforce only having one instance of this type?

Unfortunately no. There’s no way to enforce that you have only one of an object of a given type.

However, if you want to be clever, you can write a lambda query:

type Mutation {
    newState($field FIELDTYPE): ID! @lambda
}

Then add this to your resolvers (fill in the THINGSINCAPS with your actual code):

async function newState({args, graphql}) {
   // check that a State doesn't already exist 
    const a = await dql.query(`query queryState() {
        queryState(func: type(State))) {
            expand(__all__)
        }
    }`, {})
    if a.data.queryState.length == 0 {
           // add  new State
           b = await graphql( GRAPQL_CODE_TO_ADD_NEW_STATE )
           return b.data.addState.State[0].id
    }
    // return the old state ID
    return a.data.queryState.State[0].id 
}

self.addGraphQLResolvers({
    "Mutation.newState": newState
})

Now dgraph provides AddState mutations. It has to be up to you to NOT use AddState but rather use newState

@gja/@pawan might have a better solution or may want to add a constraint directive into Slash (hint hint) :stuck_out_tongue:

1 Like

Could you use @generate to avoid creating AddState?