Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional contents / GraphQL directives support #474

Open
novoj opened this issue Feb 14, 2024 · 0 comments
Open

Conditional contents / GraphQL directives support #474

novoj opened this issue Feb 14, 2024 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@novoj
Copy link
Collaborator

novoj commented Feb 14, 2024

The ultimate goal of evitaDB is to minimize the number of roundtrips between the client and the database server. There are situations where the client can decide about the requested content only at the moment when it partially reads the entity. Examples of such situations are

  1. if URL matches master product and this product has only one variant, it should be redirected directly to this variant
  2. if requested entity has certain tag, it should be rendered in different way (with different content)
  3. if requested category (hierarchical entity) is 1st level category, render only top selling product, category on 2nd and lower level will contain list of products

There are many situations that look like this.
To avoid multiple requests between client (middleware) and server, we can introduce conditional content based on GraphQL directives and define routing query like this:

query {
  getEntity(url: "/en/macbook-pro-13-2022") {    
    targetEntity {
       ... on Product {      
        attributes {
          url
        }    
        variants @include(if: attributeEquals("productType", "MASTER")) {
          a: referencedEntity @include(if: countEquals(1)) {
            attributes {
              url
            }
          }              
        }
      } 
    }
  }
}

The directives would be usable wherever the content is retrieved, and would allow different nested content at that location, provided the condition in the directive is true.

Another such example is:

query {
  getProduct(code: "macbook-pro-13-2022") {
    attributes {
      code
      productType
    }
    variants @include(if: attributeEquals("productType", "MASTER")) {
      # content
    }
    bundles @include(if: attributeInSet("productType", "STANDARD", "VARIANT")) {
      # content
    }
  }
}

I.e. fetch information about variants if the product is a master product, or fetch product bundles if the product is of standard type or is a variant product.

In the evitaQL / REST API protocol we would introduce new constraint when which would take a unique name, constraint and EntityContentRequire element (or several elements). Then it would produce new results in the extraResult part of the response that would be indexed by the unique name defined for the when, then indexed by the product primaryKey, and finally contain the fetched entity part. The client is responsible for assembling the data.

We cannot put the conditional data directly on the returned entities because the requirements may overlap and more than one may satisfy the condition. Because some reference contents allow to be filtered / ordered - we would never be able to compose the single entity content consistently for these conditional parts.

In the Java driver, we could introduce something like "scopes", which could combine the returned entity with the part of one or more conditional subparts on the level of generated proxies, provided they don't overlap. However, this would be an additional feature of the client driver that is not supported by the server side.

@novoj novoj added the enhancement New feature or request label Feb 14, 2024
@novoj novoj self-assigned this Feb 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant