Difficult logic about link

I encountered difficulties when designing the schema. My schema is as follows.

type User {
    id: String! @id
    name: String! @search(by: [term])
    followings: [User] 
    followings_count: Int
    followers: [User] @hasInverse(field: followings)
    followers_count: Int
    ...
}

Now there are two users A and B.

1,When A follows B, the A’s followings_count field will be +1, and B’s followers_count field will need +1.

This requires a lot of work:

1), Add B to A’s followings, and B’s followers will automatically add A.

2), Query A’s followings_count

3), Update A’s followings_count to followings_count+1

4), Query B’s followers_count

5), Update B’s followers_count to followers_count +1

2,When A unfollows B, Will do something similar to the above.

What’s worse is that GraphQL API does not currently support transaction, once an error occurs, the operation cannot be rolled back.

Is there a better design or method to avoid these redundant work ?

Wait until count methods/directives come to graphql. That would be much easier.

The current recommended method would be a custom field backed by DQL

You can choose to not store the count as a field, but instead just add and remove users from followings and followers. Then, you can simply write a DQL backed GraphQL query to get you the count of those fields. See the Custom DQL docs for an example.

@amaster507 @abhimanyusinghgaur Thanks for help. If the amount of data is large, will the count() query be slow?

type User {
    id: String! @id
    name: String! @search(by: [hash,term])
    followings: [User] 
    followers: [User] @hasInverse(field: followings)
    followings_count: Int @custom(dql: """
        query{
            queryFollowingsCounts(func: type(User)) {
			    followings_count: count(User.followings)
		    }
        }
    """)
    created_at: DateTime!
   ...
}

I want to implement it as above, but it doesn’t work. It prompts “@custom directive with dql can be used only on queries”.

Oh that is interesting. I have not tried DQL on custom fields, I just assumed it would work. I am at a loss of how to do this now then besides just getting all the ids and counting on the client side.

You can apply the @count index in DQL schema to make it fast. See an example here. The @count index is not yet supported in GraphQL, so for now you may need to modify the DQL schema for the predicate you want to apply the count index to.
For your schema, that can be achieved by simply applying below schema update to DQL schema using /alter endpoint after you have applied the GraphQL schema:

User.followings: [uid] @count .
User.followers: [uid] @count .

Custom DQL is not yet supported on fields, it is only supported for queries ATM. But, you do bring up an interesting use-case.
For now, you will need to design a separate custom DQL query using a @remote type as mentioned in the Custom DQL docs.