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

RFC: Custom restQL functions #35

Open
caiorcferreira opened this issue Oct 20, 2020 · 0 comments
Open

RFC: Custom restQL functions #35

caiorcferreira opened this issue Oct 20, 2020 · 0 comments
Labels
enhancement New feature or request

Comments

@caiorcferreira
Copy link
Contributor

caiorcferreira commented Oct 20, 2020

Status Proposed
PR # TBD
Author(s) Caio Ferreira
Updated 2020-11-08

Motivation

RestQL is a platform that aims to easy the work of consuming microservice ecosystems. For such, it provides numerous tools to manipulate requests and responses, one of which are built-in functions.

Currently, there are a few functions such as base64, flatten, no-multiplex, and matches. Although to become more flexible and better address the users' needs on daily basis, restQL should not rely only on these built-in functions and should allow its users to extend this set of functionalities.

However, the restQL was never thought of as a general-purpose language and runtime and as such we should not incentive the embedding of complete systems in it. That is, custom functions should be possible and simple, but not necessarily too easy and generic that would allow a user to create a complete application inside a handful of queries.

Hence, we present this design to support custom functions as plugin extensions, leveraging the current restQL toolbox.

Design Proposal

There will be two types of functions in restQL:

  1. Morphisms: responsible for transforming a value, can be used to encode a value during request building, like base64 and flatten or to filter during the response building like matches.

  2. Special forms: responsible to drastically change restQL behaviors, like no-multiplex and as-body.

By the nature of these types of functions follows that the Custom Functions can only be morphisms. Any functionality that could not be represented by a value transformation and require a change in behavior will require a Special Form to be built inside restQL.

Implemenation details

Following the pattern adopted by the restQL plugin ecosystem, a Custom Function will be a plugin that implements a proper interface, as the below draft:

type CustomFunctionPlugin interface {
  Plugin
  Construct(target interface{}, args []interface{}) Function
}


type Function interface {
  Identifier() string
  Target() interface{}
  Args() []interface{}
  Apply() interface{}
}

Therefore, the plugin will be a factory of a certain Function, which will have to implement the given interface. To contextualize, let's take a query to exemplify how each of the parameters involved. Take the query,

from hero
  with
    id = $id
    age = $age -> inc(5)

In this case, the inc function will be provided as a Custom Function. When calling the Construct method on the plugin, restQL will provide the target, that is the node upon which the transforming will take place, in this case, it will be variable $age (already resolved to a Golang primitive value, like 40), and the arguments, which are the value passed inside the parentheses.

On the other hand, the function will provide its Identifier, in this case, inc, to be used in the query, and an Apply method, which will do the heavy-lifting and where the logic will be present.

Once finished, the value returned by the function will replace the value at the Target node. In case the Target is a list then the function will be mapped over the value, being applied one time per list element.

Zero value

The functions will be able to return a zero value provided by the constant restql.NoValue. Any node which the returned value is this will be omitted. This zero value will allow functions to filter nodes in the context of the with and only blocks.

Currently, null values are already omitted when parsing with parameters to query params, however they are allowed when parsing the with parameters to a body.

With this zero value we don not overload the semantic of a null value, preserving the current behaviour and adding a tool to distinguish between actual empty nodes and unwanted ones.

Questions and Discussion Topics

Some implementation details are left off this proposal for brevity but can be addressed if its seen fit.

Suggestions and comments are welcome!

@caiorcferreira caiorcferreira added the enhancement New feature or request label Oct 20, 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

1 participant