We wanted to build an application using the GraphQL API and trying to build dynamic discovery where we can query system and get the required objects/metadata (where CRUD can be performed). We know GraphQL provides introspection query, to query the schema. Below are the few query we have identified:
query IntrospectionQuery { __schema { types { name kind ofType { name kind }} } } - To get all the types. The problem with this query is that it returns all the types (including OBJECT, INPUT_OBJECT, other types). Not all objects are top level. How to differentiate between top level object on which CRUD can be performed.
Some endpoint have generic implementation for Query and Mutation, like a kind of abstract method (Query - businessObjects, Mutation - upsert). How we can derive and map the operations on the object identified above.
We wanted to build a common module which can be applied to any GraphQL endpoint.
Thanks in advance.
Related
I am currently exploring MongoDB Realm, more specifically the GraphQL integration. I have successfully created resolvers which return a specific type, or an array of one type. However, I can't figure out how to return arrays of multiple types...
I have tried to create a custom payload, but I have to define that payload as JSON, and can't reference non-JSON types from in there.
To clarify:
I can create a custom resolver which resolves: {shirts: [Shirts]}
I cannot create a custom resolver which resolves: {shirts: [Shirts], trousers: [Trousers], shoes: [Shoes]}
I cannot create a custom resolver which resolves: {shirts: [Shirts], isFoo: Boolean}
Is there any way to accomplish the latter two? I would be able to do it if I was allowed to edit the GraphQL schema directly, but as far as I can see, one is only able to modify the schema through this custom resolver interface...
Thanks in advance!
I recently moved from Array to RealmCollectionType because it provides more effective filters. Now I want to migrate my unit-tests as well, but I don't like the In-memory Realm because it requires me to setup a lot of links and relations between my objects. I was trying to mock Results and LinkingObjects by conforming my mock to RealmCollectionType. Unfortunately, I'm stuck implementing filter operation because it should return Results which is declared as final.
What is the purpose of filters to narrow it's return type to Results?
RealmCollection.filter(...) returns a Results because that's the query result container in Realm. It does share some common interface elements with other collection types in Realm (like LinkingObjects and List), which is why it conforms to the RealmCollection protocol.
If you'd like to test code that's generic on say the Collection protocol in the Swift standard library, which RealmCollection inherits from, you can do so.
I have a working project with the following layers:
DataAccess - The project hits multiple DBs and web services. This layer defines the interfaces to each of them. It exposes the native types for each source (EF types for DBs, SOAP-defined types for web services, etc.). Let's say it exposes an EFProject and SoapProject.
Repository - This layer stiches results from the various sources to form a single entity, and exposes it. Let's call this ModelProject
Service - Adds REST attributes to to the entity (action links, etc.). This exposes a ProjectDTO.
WebApi - The controller spits out the ProjectDTO directly.
I'm trying to implement OData, specifically to page the results of very large queries. I've read a lot of examples, but they all seem to expose the source objects directly, and then map them to the final DTOs in the controller.
I would like to somehow push the ODataQueryOptions down to the Repository. This would allow me to keep the existing structure, and pass the query logic down to SQL. I understand that, because the ODataQueryOptions reference the ProjectDTO type, they can't be applied until an object of that type is available. Is there a way to "translate" the ODataQueryOptions from one type to another? Is there another way of doing this that I'm not aware of?
It is able to change the ODataQueryOptions, and such actions in a controller are for you to handle the options yourself:
public IQueryable Get(ODataQueryOptions queryOptions)
public IQueryable Get(int key, ODataQueryOptions queryOptions)
Here is a sample about this:
https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataQueryableSample/Controllers/OrdersController.cs .
For your reference, the source code of ODataQueryOptions is: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.OData/OData/Query/ODataQueryOptions.cs
Is there a way to "translate" the ODataQueryOptions from one type to another? Is there another way of doing this that I'm not aware of?
There is a way to actually translate the IQueryable<DomainModel> to IQueryable<DtoModel>.
I've done something similar in the past by leveraging AutoMapper's projection functionality. By calling the Project<TSource>/To<TTarget> methods, you can change an IQueryable that points to your domain models to another IQueryable that targets the Dto models, without actually executing it.
This means that you can now perform any OData operations on the DTO level and they will transfer through projection to the DAL layer into EntityFramework and SQL. In a scenario like this, there shouldn't be any need to manually handle the query logic so you can just use [EnableQuery] on the API route and let OData do its thing on the resulting IQueryable<DtoModel>.
I used this very successfully in one of the projects I worked on: as long as you rely just on AutoMapper projection to convert the types, it should work fine.
Granted, you can't do a lot of fancy mapping that way. The project methods will not be able to apply all kinds of mappings that you create, so I recommend checking the documentation on that front.
You also have to keep in mind that the original IQueryable needs to be exposed outside of the repository layer for this to work properly, otherwise the query will be executed too early. Some people will find that a boundary violation and will advocate for materializing the query inside the repository layer, but I don't have an issue with that particular aspect.
I have a situation where I will be using a repository pattern and pulling objects from the database with a lazy loaded GetAll method that returns IQueryable. However I also need to build dynamic objects that will be included with the lazy loaded objects(query).
Is it possible to add built objects to a lazy loaded IQueryable and still keep the lazy loaded benefits? For instance
public override IQueryable<Foo> GetAll()
{
return _entities; // lazy loaded
}
public override IQueryable<Foo> GetAllPlusDynamic()
{
var entities = GetAll();
foreach(var d in GetAllDynamic())
{
entities.Add(d); // eagerly loaded
}
return entities;
}
I am unsure if I understand you correctly but refering to your comment...
Yes, basically query the database for a set of objects and then query
another data source (in this case a service) and build a set of
objects.
... I would say that it's not possible.
An object of type IQueryable<T> used with Entity Framework (LINQ to Entities) is basically a description of a query which the underlying data store can execute, usually an abstract description (expression tree) which gets translated into SQL.
Every part of such a query description - where expressions, select expression, Any(...) expressions, etc. - must be translatable into the native language (SQL) of the data store. It's especially not possible to include some method calls - like a service call - in an expression that the database cannot understand and perform.
IQueryable<T> knows an underlying "provider". This provider is responsible to translate the expression tree hold by the IQueryable<T> object into "something", for example T-SQL used by SQL Server, or the SQL dialects used by MySQL or Oracle. I believe it's possible to write your own provider which might then be able to perform somehow the service calls and the database queries. But I also believe that this is not an easy task.
Using the standard SQL providers for Entity Framework you have to perform database query and calling the service separately one after each other: Run query and materialize entities in memory - then run the service call on the result collection for each entity.
I have a question about how to do data filtering with RequestFactory in GWT. I am currently working on an application which is backed by a MySQL database. My persistence layer is based on JPA/Hibernate. I am using RequestFactory to query my database for all my listing-related operations.
So for example, I have a Person object : In my PersonRequestContext I have a method which allows me to list persons. The method signature is :
Request<List<PersonProxy>> listPersons(Integer firstResult, Integer maxResults);
As you may have guessed, the corresponding query is something like this :
entityManager.createQuery("SELECT p FROM Person p ORDER BY p.id").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
Now, I would like to filter the result based on table columns. So I wanted to use some kind of Filter class abstraction to solve it. The problem is that as we all know, it's not possible to pass non-primitive objects in to the requestFactory method.
Have you ever experienced this kind of thing ? And how did you deal with it to solve the problem?
Your assertion that only primitive types can be passed to a Request method is incorrect. See the documentation on transportable types. You can create a ValueProxy hierarchy to model your filters.