Relationships with Virtual Models in Ecto


I have a question on non database-backed models in Ecto.

The app I’m building is similar to Swagger Hub where API developers document their API. So imagine a user who built a “tasks” API can define their API schema (eg defining which fields exist on Task), create Operations (eg POST to /tasks), define authentication (eg an authentication token on every request), etc.

The models and their relationships might look like: an Account owns an API which owns a list of child Types (ie custom types such as a Task definition) which can have relationship with other custom Types. An API might also own a list of child Operations which also have relationships with custom Types.

However, for various reasons, I’d like all of this data about the API to be persisted as JSON in the Open API spec ( in the database instead of having an Operations table, a Types table, etc. The “actual” relationships might be an Account (stored as a regular table) has an API (stored as a regular table) which has a api_spec json field.

My question is: how can I make this an implementation detail encapsulated to a small part of the app while the rest of the app treats these virtual models (and their relationships to other models) as regular, database-backed models? I’d like to follow standard patterns for the forms, validations, etc. and just have custom serialization/deserialization logic when it comes to loading/persisting this data.

Should I use embedded_schema? If so, would any model that has a relationship with a virtual model “embed” that relationship?



1 Like

Yes, it sounds like you can define embedded Schemas to describe the json document and then embed the root api_spec as jsonb in the API table.

Can you give an example of the relationship you need to model?

You may also be interested in OpenApiSpex which defines struct types for most of OpenAPI 3:

Thanks, @mbuhot!

Here is an example relationship:

A user might define a Todo type that consists of a name, and an isDone boolean. That custom Type would belong_to that user’s API. Secondly, the create Operation might require that Todo in its request body which means Types might also belong_to Operations (or Operation). Thirdly, Types might incorporate other Types (think of a special timestamp that is used on different types) so their might be a parent/child relationship from Types to other Types.

Regardless, I can probably figure out whether these are one-to-one, one-to-many, etc. but my question is: given these are all “virtual models” should they be like this:

  schema "types" do
    belongs_to :api, API


  embedded_schema do
    belongs_to :api, API

Concerning OpenApiSpex, I actually took a look but wasn’t sure the best way to extract just what I needed given it was built more for actual APIs. Any suggestions? Again, I’m creating forms where users would define their custom types, define the API operations, etc.