vuestorefront / storefront-api

Storefront GraphQL API Gateway. Modular architecture. ElasticSearch included. Works great with Magento1, Magento2, Spree, OpenCart, Pimcore and custom backends
https://storefrontapi.com
MIT License
8 stars 1 forks source link

Add typed standard for listing resolvers #20

Open pkarw opened 4 years ago

pkarw commented 4 years ago

What is the motivation for adding/enhancing this feature?

If we managed to introduce a single standard of list function between resolvers it could be a potentially nice feature to re-use between modules.

Take this list products it's then used for listing category products

In this case, the source is Elastic Search but it can be any other data source including graphQL, REST etc.

Having it this way we can pretty nicely merge different data sources - eg. having a list function from the WordPress module we can add even something like category.posts() to get the blog posts along with the products for a specific category

Kind of Schema Stitching or Federation BUT over different data sources - Stichting REST, Database whatever with the GraphQL - so the list function becomes a universal data source no matter wich service

It's an idea similar to DataResolvers from Vue Storefront - but it's simpler. I guess we could extend the module API adding something like this:

export interface DataProviderMappings {
  list: any
}
export interface StorefrontApiModuleConfig {
  key: string,
  initMiddleware?: (context: StorefrontApiContext) => void,
  initApi?: (context: StorefrontApiContext) => void,
  initGraphql?: (context: StorefrontApiContext) => GraphqlConfiguration,
  registerDataProviders?: (context: StorefrontApiContext) => DataProviderMappings,
  loadMappings?: (context: StorefrontApiContext) => ElasticSearchMappings,
  beforeRegistration?: (context: StorefrontApiContext) => void,
  afterRegistration?: (context: StorefrontApiContext) => void
}

so on the module level the user can call something like this:

export const WordpressIntegrationModule: StorefrontApiModule = new StorefrontApiModule({
  key: 'wordpress',
  registerDataProviders: ({ config, db, app }: StorefrontApiContext): DataProviderMappings => {
    return {
      list: {
        'posts': ,
        'categories': async ({ filter: any, sort: string, currentPage:int, pageSize:int, search:string, context:any, rootValue:any, _sourceInclude:string[], _sourceExclude:string[] }) => {
return postsList
}
      }}
  }
})

... so then - from the other module user could call something like:

const posts = await ModuleDataProvider.list.posts( { pageSize: 10 })
pkarw commented 4 years ago

@ResuBaka this is something you could be realy interested in - this API will let us to attract integration developers to add their integrations as modules to SFAPI

pkarw commented 4 years ago

@ResuBaka maybe instead of ModuleDataProvider singleton we should have some Registry object available thru the context as well? I guess we should avoid singletons

pkarw commented 4 years ago

Related: #23 - having this registry of data fetching functions all in the same format we can easily switch between output and query formats (graphql, odata, rest)