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

Spike: Discover and define models at runtime #2484

Closed
4 tasks done
bajtos opened this issue Feb 26, 2019 · 5 comments
Closed
4 tasks done

Spike: Discover and define models at runtime #2484

bajtos opened this issue Feb 26, 2019 · 5 comments
Assignees
Labels
feature parity Relations Model relations (has many, etc.) spike
Milestone

Comments

@bajtos
Copy link
Member

bajtos commented Feb 26, 2019

Certain applications don't use static JSON files to define their models, they create model definitions at runtime, often by running model discovery to obtain the model schema. Once the model is defined, the application usually exposed it via REST API.

This can be easily done in LB 3.x as follows:

const MyModel = app.registry.createModel(name, properties, settings);
app.model(MyModel, {dataSource: 'some-datasource', public: true});

Let's find out how to allow LB 4.x users to do the same.

The scope of this spike is to research solutions for discovering and defining models in such way, that the infrastructure implemented in #2036 can pick up new definitions and build REST APIs.

Acceptance criteria

  • A proof-of-concept implementation of the necessary run-time parts.

  • A demo application providing a new REST API endpoint that will:

    1. Accept a MySQL connection string (host+port+database+credentials) and a list of table names.
    2. Connect to the specified MySQL database.
    3. Discover model schemas from the given tables
    4. Define LB4 models for the given tables
    5. Expose these models via REST API using From model definition to REST API with no custom repository/controller classes #2036
    6. Return a list of URL paths of the newly added models (e.g. /Products, /CoffeeShops)

    We can use the public database from loopback-getting-started) when testing this new endpoint manually.

  • List of GitHub issues - follow-up user stories covering the implementation. Documentation and blog post should be included in the implementation plan.

  • Decide what to do about relations. The story [EPIC] From relation definition to REST API with auto-generated repository/controller classes #2483 is tracking REST API for relations, but I don't think it's a good idea to include relations in the first iteration. Create a new GH issue to add support for discovery & definition of relations, this new issue can be a spike or the real implementation, depending on whether the implementation would be clear enough.

@bajtos bajtos added spike Relations Model relations (has many, etc.) feature parity 2019Q2 labels Feb 26, 2019
@bajtos bajtos changed the title Spike: discover and define models at runtime Spike: Discover and define models at runtime Feb 26, 2019
@jannyHou
Copy link
Contributor

Things to consider when do the spike:

  • We probably need an open model class(weakly-typed model class) which allows any property
    • Model metadata describes the data shape of backend
    • This story is particular for relational databases(at least the first iteration let's focus on relational dbs)
    • Model instance is used in CRUD operations
  • What is the run time representation of the discovered model
  • Take the validation into consideration: using model definition for validation

@bajtos bajtos added the p2 label Apr 9, 2019
@dhmlau dhmlau added 2019Q3 and removed 2019Q2 labels Apr 16, 2019
@dhmlau dhmlau added 2019Q4 and removed 2019Q3 labels Jun 25, 2019
@bajtos
Copy link
Member Author

bajtos commented Sep 3, 2019

Here is a code snippet/mock-up that I wrote while discussing this feature recently:

const ds = new DataSource({/*config*/})
const discovered = await ds.connector.discover();
/* 
{
  name: 'Product',
  properties: {
    'name': {
      type: 'string'
    }
  }
}
*/

// we need to transform modelDefinitionData slightly
for (prop of discovered.properties) {
  if (Array.isArray(prop.type)) {
    prop.type = {
      type: 'array',
      itemType: prop.type[0],
    }
  }
}

// Create model definition
const modelDef = new ModelDefinition(discovered);

// Create model class
// FIXME: create a named class using a template Function factory
const modelCtor = class extends Entity {};
modelCtor.modelName = discovered.name;
modelCtor.definition = modelDef;

@dhmlau dhmlau removed the 2019Q4 label Oct 3, 2019
@dhmlau dhmlau added the 2019Q4 label Oct 23, 2019
@bajtos bajtos self-assigned this Dec 2, 2019
@bajtos bajtos added this to the Dec 2019 milestone Dec 2, 2019
@bajtos
Copy link
Member Author

bajtos commented Dec 2, 2019

Spike in progress: #4235

@bajtos
Copy link
Member Author

bajtos commented Dec 12, 2019

Follow-up stories:

I am closing this spike as done.

@bajtos bajtos closed this as completed Dec 12, 2019
@bajtos
Copy link
Member Author

bajtos commented Dec 12, 2019

Decide what to do about relations. The story #2483 is tracking REST API for relations, but I don't think it's a good idea to include relations in the first iteration. Create a new GH issue to add support for discovery & definition of relations, this new issue can be a spike or the real implementation, depending on whether the implementation would be clear enough.

I don't think we will have time to look into this in the next 3-6 months. Let's wait until there is user demand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature parity Relations Model relations (has many, etc.) spike
Projects
None yet
Development

No branches or pull requests

3 participants