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

Params JsonObject #49

Open
zajcu opened this issue Oct 2, 2019 · 4 comments
Open

Params JsonObject #49

zajcu opened this issue Oct 2, 2019 · 4 comments
Assignees
Labels
enhancement New feature or request

Comments

@zajcu
Copy link

zajcu commented Oct 2, 2019

Is your feature request related to a problem? Please describe.
In databridge 1.5.0 version there was a awesome feature: params
https://github.com/Knotx/knotx-data-bridge/tree/1.5.0
What is missed in current 2.0 version

Describe the solution you'd like
We need similar feature in 2.x version. For example to cover example code:
`<knotx:snippet data-knotx-task-item="bookslist" data-knotx-bookslist-params-item='{"queryParams":{"q": "java"}}' data-knotx-task-item2="userlist" data-knotx-userlist-params-item2='{{"queryParams":{"name":"John Doe"}}'>

{{item._result.book.name}}

{{item2._result.user.name}}

...`

I supposed the simple solution will be extend fragments model to have additional JsonObject property, and later in processing consume it for example in HttpAction like it was in old implementation in HttpClientFacade (1.5.0 version).

Potentialy this object can be reused in other places.

What do you think?

Additional context
We have used it a lot in our current project, we need this to start migrate !X to the last version.

@tomaszmichalak
Copy link
Member

tomaszmichalak commented Oct 2, 2019

Hi @zajcu,
thanks for the issue. In Knot.x 1.5.0 it was possible to specify the params attribute that overrode the one from the [dataDefinitions[namespace].params] configuration attribute, see the example. So it was easy to specify the new path for the named HTTP data source (REST endpoint). Please note that in Knot.x 1.5.0 it was possible to define many data sources per fragment.

In Knot.x 2.0.0 we introduced a task concept where you can define only one task per fragment.

<knotx:snippet data-knotx-task="booklist"
</knotx:snippet>

Then in the configuration we have:

tasks {
    booklist {
        actions = [
            { action = books }
            { action = authors }
        ]
        onTransitions {
            _success {
                action = template-engine-handlebars
            }
        }
    }
}

Task can specify one and more actions to execute, in this example we have two actions: books and authors.
Our actions call REST endpoints and fill the payload. Every action gets Fragment, do some transformation and responds with the new Fragment.
In Fragment there is the configuration attribute, it is a JSON object. For HTML markup, it contains all knotx:snippet tag attributes. So it is not required to extend Fragments model with extra attribute.
When you check the Http Action documentation you will find that you can parametrize your action with:

  • request data
  • payload data
  • configuration data

You can check available placeholders here. Maybe it is worth to add the example for configuration attributes, like {config.books-query}. This attribute can be specified with:

<knotx:snippet data-knotx-task="booklist" books-query="java"
</knotx:snippet>

So then in the action configuration, you will have:

book {
  factory = http
  config {
    endpointOptions {
      path = /service/mock/book.json?q={config.books-query}
      domain = localhost
      port = 3000
      allowedRequestHeaders = ["Content-Type"]
    }
  }
}

Can you please verify if it works for you? Our intention was to simply tag attributes.

@tomaszmichalak
Copy link
Member

Thank you @zajcu for your input. As we discussed this solution works as expected. However, we discovered new requirements. Let me explain it with the example below:

ZG Bridge integrates with Knot.x to deliver dynamic data to templates coming from AEM. ZG Bridge defines collections and collections items that can be easily used during AEM authoring.

So, let's imagine that we have two independent collections: authors and books. Both authors and books are JSON objects coming from REST API. JSON is a contract, REST API is a data source. There are two REST endpoints for authors:

/authors?filter="first name"
/author/{id}

and books:

/books?filter="title"
/book/{id}

Then in ZG Bridge you can specify what items are used to fill a template from AEM. In this way, we can specify two books at a single page (first - the primary one, second - the recommended one).
So we have book-1 and book-2. This data must be configured something in HTML, then Knot.x can use it and fill the template.

The example HTML markup can look like:

<knotx:snippet task="product-details-component"> 
{{book.1.title}}
<h1>Recommended products</h1>
{{book.2.title}}
</knotx:snippet>

In Knot.x there is the product-details-component task defined. In the standard approach, we would define it as:

tasks {
    product-details-component {
        actions = [
            { action = book1 }
            { action = book2 }
        ]
        onTransitions {
            _success {
                action = template-engine-handlebars
            }
        }
    }
}

and specify two actions. But as you see this solution is not very flexible. So we need some configuration to make those task definitions more dynamic.

Let's change the task configuration to:

tasks {
    product-details-component {
        actions = @book
        onTransitions {
            _success {
                action = template-engine-handlebars
            }
        }
    }
}

Then we can configure @book with some parameter in HTML

<knotx:snippet task="product-details-component" task-actions="@books-configuration"> 
{{book.1.title}}
<h1>Recommended products</h1>
{{book.2.title}}
</knotx:snippet>

, where the @books-configuration structure is:

{
  "book": [
    {
      "namespace": 1,
      "config": {
        "id": 1
      }
    },
    {
      "namespace": 2,
      "config": {
        "id": 2
      }
    }
  ]
}

With this solution we specify Action once:

actions {
  book {
    factory = http
    config {
      endpointOptions {
        path = /book/{config.id}
        ...
      }
    }
  }
}

Then we can specify the dynamic task provider implementation that would transform the task-actions attribute to Task.

@zajcu
Copy link
Author

zajcu commented Oct 9, 2019

Thank you @tomaszmichalak this is exactly what we need to cover our requirements. By the way very nice explanation.

@tomaszmichalak tomaszmichalak self-assigned this Oct 10, 2019
@tomaszmichalak
Copy link
Member

tomaszmichalak commented Oct 15, 2019

Hi,
we had a design session, those are outputs:

  • task building should be extendable, it means that projects should be able to deliver their custom implementation if needed (for example, task can be configured externally)
  • the current configuration should not be affected, it should be as simple as possible:
tasks {
  simple-task {
    action = aAction
    onTransitions {
      _success {
        action = te-hbs
      }
    }
  }
}
  • the current behaviour is delivered via the default task factory, the example simple-task can be configured as:
tasks {
  simple-task {
    factory = default
    metadata {
      taskKey = "data-knotx-task"  
    }
    config {
      action = aAction,
        onTransitions {
          _success {
          action = te-hbs
        }
      }
    }
  },
  • we deliver the second pre-configured task factory handling dynamic task configuration:
tasks {
  some-template-task {
    factory = pre-configured
    metadata {
      taskKey = "data-knotx-task"  
    }
    config {
      actions = [ @customActions ]
      onTransitions {
        _success {
          action = te-hbs
        }
      }
    }
  }
}
  • no changes in actions are required:
actions {
  aAction { },
  bAction { },
  te-hbs {
    factory = knot,
    config {
      address = knotx.knot.te.handlebars,
      deliveryOptions {
        sendTimeout = 1000
      }
    }
  }
}

tomaszmichalak added a commit that referenced this issue Nov 26, 2019
…ub.com:Knotx/knotx-fragments into feature/#49-node-factories-with-common-configs
tomaszmichalak added a commit that referenced this issue Nov 27, 2019
…ub.com:Knotx/knotx-fragments into feature/#49-node-factories-with-common-configs
tomaszmichalak added a commit that referenced this issue Nov 28, 2019
…ub.com:Knotx/knotx-fragments into feature/#49-node-factories-with-common-configs
tomaszmichalak added a commit that referenced this issue Nov 28, 2019
…mon-configs

Feature/#49 node factories with common configs
@tomaszmichalak tomaszmichalak added the enhancement New feature or request label Jan 2, 2020
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

2 participants