Comments (4)
My initial idea for supporting relationships was to mimic the ecto relationships.
This way it will be easy to maintain the support for ecto models.
The idea is to have the same functions ecto have to check the relationships.
__schema__(:associations)
returns all association names.
__schema__(:association, name)
returns the association reflection.
I actually implemented those functions (without the reflections), you can take a look here.
An association reflection in ecto looks like this:
# BelongsTo
%Ecto.Association.BelongsTo{cardinality: :one, defaults: [], field: :company,
on_cast: nil, on_replace: :raise, owner: App.Activity,
owner_key: :company_id, queryable: App.Company,
related: App.Company, related_key: :id, relationship: :parent}
# HasOne
%Ecto.Association.Has{cardinality: :one, defaults: [], field: :department,
on_cast: nil, on_delete: :nothing, on_replace: :raise,
owner: App.Activity, owner_key: :id,
queryable: App.Department, related: App.Department,
related_key: :activity_id, relationship: :child}
# HasMany
%Ecto.Association.Has{cardinality: :many, defaults: [],
field: :product_activities, on_cast: nil, on_delete: :nothing,
on_replace: :raise, owner: App.Activity, owner_key: :id,
queryable: App.ProductActivity, related: App.ProductActivity,
related_key: :activity_id, relationship: :child}
We don't need to add all these fields only the ones dayron needs
Ecto also have the Ecto.Association.NotLoaded
module to indicate an association
is not loaded.
Having all this information about the associations I think we can easily parse the relationships.
Maybe adding a method build
in every Model
that will first build the associations if they're present
and only after that call the struct
method.
If we add support for all this I think adding the api to fetch associations will be straightforward.
from dayron.
So, I'm thinking in adding support for has_many
, has_one
and belongs_to
.
Here's a draft of the api.
The Dayron.Model will now support the has_many
, has_one
and belongs_to
keys.
The value of this keys would be keyword lists
defmodule MyApp.User do
# api requests to http://api.example.com/users
use Dayron.Model, resource: "users", has_many: comments: Comment
# struct defining model attributes
defstruct name: "", age: 0
end
defmodule MyApp.Comment do
use Dayron.Model, resource: "comments", belongs_to: user: MyApp.User
defstruct text: ""
end
Support for the ecto schema will still be the same
defmodule MyApp.User do
use Ecto.Schema
use Dayron.Model
schema "users" do
field :name, :string
field :age, :integer, default: 0
has_many :comments, MyApp.Comment
end
end
defmodule MyApp.Comment do
use Ecto.Schema
use Dayron.Model
schema "comments" do
field :text, :string
belongs_to: :user, MyApp.User
end
end
And the api will be used like this:
RestRepo.all(post, :comments) # => get users/:id/comments
RestRepo.get(post, :comments, comment_id) #=> get users/:id/comments/:comment_id
RestRepo.update!(post, :comments, comment_id, comment_params) # => put users/:id/comments
RestRepo.insert!(post, :comments, comments_params) #=> post users/:id/comments
RestRepo.delete!(post, :comments, comment_id) #=> delete users/:id/comments/:id
For now I'm not planing to suport nested preloads
like RestRepo.get(post, [:comments, :attachments], comment_id)
but this can be added in the future.
Also, if the json response already have the relationships, it will be parsed normally.
GET users/1
{id: 1, name: "john doe", comments: {id: 1, text: "that's a comment"}}
The Post
returned by this get
will have the comment property already loaded.
In this case I'm thinking in adding the RestRepo.assoc_loaded?(post, :comments)
so
the user can check this before sending another request.
What do you think?
from dayron.
Thinking a little bit better, I think #43 and #44 should be done before this because for this to work we will need to support data mapping for ecto relationships.
from dayron.
@tiagoengel I like your proposal, and also agree with other tasks dependencies. It's a good plan to check Ecto 2 changes before going with this.
from dayron.
Related Issues (20)
- Read config from System Env
- add a dayron.response/dayron.error
- implement inspect for better logging
- Extract logger to an behavior
- Add associations/embed data mapping
- Better integration with Ecto.Schema
- Support custom actions: request method and url
- Support a pipeline of "plugs" to change request/response
- Accept Ecto.Changesets
- Mix task to install Dayron
- Mix tasks to generate a Model/Resource HOT 2
- Add an authenticated requests example
- Circuit breaker integration HOT 2
- Documentation code links do not work HOT 1
- Create a Tesla Adapter HOT 8
- Allow specifying top-level attribute, possibly overriding `__from_json_list__: 2` HOT 2
- Dynamic atom keys
- Get request encode empty body to "" - Throw 403 forbidden response from some API HOT 3
- Supporting different json list structure when retrieving data HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dayron.