0

I understand a filter condition can be applied in a query e.g

query{
    MyObject(where: {id: {eq: 1}}){
        id
        name
    }
}

which would access the server side query:

[UseDbContext(typeof(dbContext))]
    [UseProjection]
    [UseFiltering]
    [UseSorting]
    public IQueryable<MyObject> GetMyObject([ScopedService] dbContext context)
    {
        return context.MyObject;
    }

This can also be expressed on the server side query e.g (.Net implementation).

query{
    GetMyObjectById(id: 1){
        id
        name
    }
}

public async Task<MyObject> GetMyObjectById(int id)
{
    return dbContext.MyObject.FindAsync(id);
}

My question is, why would one be used over the other?

Ryn901
  • 173
  • 2
  • 12

1 Answers1

0

I've seen the advice (quite widespread) to use both approaches simultaneously. But slightly different implementation is usually suggested for the second case. They suggest accepting an array of ids (not the single one) in order to be able to receive the batch of the objects with a single query. Even further, it is advised to use the batch loader to merge all ids across all different requests for users, which would make the query even more efficient.

In the first versions of our API we followed the described way, but now we are going to remove the second approach for all our entities if the first approach is in place for them. As we see in the clients of our API there's no need to hold two versions of getting entities, the clients are happy to use a single endpoint for that. The first approach is flexible enough to cover all our needs. Whether we want to query by a single Id, by multiple ids, or by any search predicate - everything can be easily done with that single endpoint.

One more technical point: if, however, you want to keep the method with the id, consider accepting arrays of ids if it is important for you to use [UseProjection] in order to cut the materialization costs. FindAsync will obviously materialize all the fields of the object, but in case you return IQueryable over ids you could apply [UseProjection] to that queryable.

ademchenko
  • 585
  • 5
  • 18