KED-2020 / api-mind-map

1 stars 1 forks source link

Representers #1

Closed Kyeg closed 3 years ago

Kyeg commented 3 years ago

Create representers for your domain entities/values

Kyeg commented 3 years ago

The representer of inbox (& HATEOAS) seems successful:

>  MindMap::Database::InboxOrm.all
+----+-------+------------+--------------+---------------------------+---------------------------+
| id | url   | name       | description  | created_at                | updated_at                |
+----+-------+------------+--------------+---------------------------+---------------------------+
| 78 | 12345 | Test Inbox | A test inbox | 2020-12-06 18:03:06 +0800 | 2020-12-06 18:03:06 +0800 |
+----+-------+------------+--------------+---------------------------+---------------------------+
1 row in set

> db_inbox = MindMap::Repository::Inbox::For.klass(MindMap::Entity::Inbox).find_id(78)

> inbox_json = MindMap::Representer::Inbox.new(db_inbox).to_json

> puts inbox_json
{"name":"Test Inbox","description":"A test inbox","url":"12345","suggestions":[{"name":"tensorflow","description":"An Open Source Machine Learning Framework for Everyone","html_url":"https://github.com/tensorflow/tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"TensorFlow","description":"Project containig related material for my TensorFlow articles","html_url":"https://github.com/romeokienzler/TensorFlow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"TensorFlow-Examples","description":"TensorFlow Tutorial and Examples for Beginners (support TF v1 & v2)","html_url":"https://github.com/aymericdamien/TensorFlow-Examples","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow2_tutorials_chinese","description":"tensorflow2中文教程,持续更新(当前版本:tensorflow2.0),tag: tensorflow 2.0 tutorials","html_url":"https://github.com/czy36mengfei/tensorflow2_tutorials_chinese","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow-zh","description":"谷歌全新开源人工智能系统TensorFlow官方文档中文版","html_url":"https://github.com/jikexueyuanwiki/tensorflow-zh","created_at":"2020-12-06 18:03:08 +0800"},{"name":"eat_tensorflow2_in_30_days","description":"Tensorflow2.0 🍎🍊 is delicious, just eat it! 😋😋","html_url":"https://github.com/lyhue1991/eat_tensorflow2_in_30_days","created_at":"2020-12-06 18:03:08 +0800"},{"name":"awesome-tensorflow","description":"TensorFlow - A curated list of dedicated resources http://tensorflow.org","html_url":"https://github.com/jtoy/awesome-tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"models","description":"Models and examples built with TensorFlow","html_url":"https://github.com/tensorflow/models","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow","description":"图解tensorflow 源码","html_url":"https://github.com/yao62995/tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"examples","description":"TensorFlow examples","html_url":"https://github.com/tensorflow/examples","created_at":"2020-12-06 18:03:08 +0800"},{"name":"docs","description":"TensorFlow documentation","html_url":"https://github.com/tensorflow/docs","created_at":"2020-12-06 18:03:08 +0800"},{"name":"DCGAN-tensorflow","description":"A tensorflow implementation of \"Deep Convolutional Generative Adversarial Networks\"","html_url":"https://github.com/carpedm20/DCGAN-tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"stanford-tensorflow-tutorials","description":"This repository contains code examples for the Stanford's course: TensorFlow for Deep Learning Research. ","html_url":"https://github.com/chiphuyen/stanford-tensorflow-tutorials","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow_practice","description":"tensorflow实战练习,包括强化学习、推荐系统、nlp等","html_url":"https://github.com/princewen/tensorflow_practice","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow_cookbook","description":"Code for Tensorflow Machine Learning Cookbook","html_url":"https://github.com/nfmcclure/tensorflow_cookbook","created_at":"2020-12-06 18:03:08 +0800"},{"name":"TensorFlow-Tutorials","description":"TensorFlow Tutorials with YouTube Videos","html_url":"https://github.com/Hvass-Labs/TensorFlow-Tutorials","created_at":"2020-12-06 18:03:08 +0800"},{"name":"TensorFlow-Course","description":":satellite: Simple and ready-to-use tutorials for TensorFlow ","html_url":"https://github.com/instillai/TensorFlow-Course","created_at":"2020-12-06 18:03:08 +0800"},{"name":"Reinforcement-learning-with-tensorflow","description":"Simple Reinforcement learning tutorials","html_url":"https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"facenet","description":"Face recognition using Tensorflow","html_url":"https://github.com/davidsandberg/facenet","created_at":"2020-12-06 18:03:08 +0800"},{"name":"SSD-Tensorflow","description":"Single Shot MultiBox Detector in TensorFlow","html_url":"https://github.com/balancap/SSD-Tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"Tensorflow-Tutorial","description":"Tensorflow tutorial from basic to hard","html_url":"https://github.com/MorvanZhou/Tensorflow-Tutorial","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow-tutorial","description":"Example TensorFlow codes and Caicloud TensorFlow as a Service dev environment.","html_url":"https://github.com/caicloud/tensorflow-tutorial","created_at":"2020-12-06 18:03:08 +0800"},{"name":"TensorFlow","description":"Deep Learning Zero to All - Tensorflow","html_url":"https://github.com/deeplearningzerotoall/TensorFlow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow","description":"TensorFlow for R","html_url":"https://github.com/rstudio/tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow-wavenet","description":"A TensorFlow implementation of DeepMind's WaveNet paper","html_url":"https://github.com/ibab/tensorflow-wavenet","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow_tutorials","description":"From the basics to slightly more interesting applications of Tensorflow","html_url":"https://github.com/pkmital/tensorflow_tutorials","created_at":"2020-12-06 18:03:08 +0800"},{"name":"tensorflow","description":"使用谷歌开源的TensorFlow进行一系列的训练实践","html_url":"https://github.com/luyishisi/tensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"EffectiveTensorflow","description":"TensorFlow tutorials and best practices.","html_url":"https://github.com/vahidk/EffectiveTensorflow","created_at":"2020-12-06 18:03:08 +0800"},{"name":"stylegan","description":"StyleGAN - Official TensorFlow Implementation","html_url":"https://github.com/NVlabs/stylegan","created_at":"2020-12-06 18:03:08 +0800"},{"name":"TensorFlow-Tutorials","description":"Simple tutorials using Google's TensorFlow Framework","html_url":"https://github.com/nlintz/TensorFlow-Tutorials","created_at":"2020-12-06 18:03:08 +0800"}],"links":[{"rel":"self","href":"http://localhost:9090/api/v1/inboxs/Test Inbox"}]}
=> nil

> inbox.name
=> "Test Inbox"

> inbox.description
=> "A test inbox"

> inbox_withlink = MindMap::Representer::Inbox.new(MindMap::Response::OpenStructWithLinks.new).from_json(inbox_json)
> inbox_withlink.links['self'].href
=> "http://localhost:9090/api/v1/inboxs/Test Inbox"
Kyeg commented 3 years ago

But the representer of document seems failed: It looks like a Dry::Struct::Error will occur if the origin_id in the Document Entity is nil !?

> MindMap::Database::DocumentOrm.all
+------+-----------+---------------------------------+---------------------------------+---------------------------------+---------------------------+---------------------------+
| id   | origin_id | name                            | description                     | html_url                        | created_at                | updated_at                |
+------+-----------+---------------------------------+---------------------------------+---------------------------------+---------------------------+---------------------------+
| 1917 |           | tensorflow                      | An Open Source Machine Learn... | https://github.com/tensorflo... | 2020-12-06 18:03:08 +0800 | 2020-12-06 18:03:08 +0800 |
| 1918 |           | TensorFlow                      | Project containig related ma... | https://github.com/romeokien... | 2020-12-06 18:03:08 +0800 | 2020-12-06 18:03:08 +0800 |
| 1919 |           | TensorFlow-Examples             | TensorFlow Tutorial and Exam... | https://github.com/aymericda... | 2020-12-06 18:03:08 +0800 | 2020-12-06 18:03:08 +0800 |
.
.
.
| 1944 |           | EffectiveTensorflow             | TensorFlow tutorials and bes... | https://github.com/vahidk/Ef... | 2020-12-06 18:03:08 +0800 | 2020-12-06 18:03:08 +0800 |
| 1945 |           | stylegan                        | StyleGAN - Official TensorFl... | https://github.com/NVlabs/st... | 2020-12-06 18:03:08 +0800 | 2020-12-06 18:03:08 +0800 |
| 1946 |           | TensorFlow-Tutorials            | Simple tutorials using Googl... | https://github.com/nlintz/Te... | 2020-12-06 18:03:08 +0800 | 2020-12-06 18:03:08 +0800 |
+------+-----------+---------------------------------+---------------------------------+---------------------------------+---------------------------+---------------------------+
30 rows in set

> db_document = MindMap::Repository::For.klass(MindMap::Entity::Document).find_id(1917)
Traceback (most recent call last):
       13: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/bin/irb:23:in `<main>'
       12: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/bin/irb:23:in `load'
       11: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
       10: from (irb):2
        9: from /Users/kyeg_logos_mac/GitHub_Box/api-mind-map/app/domain/favorites/repositories/documents.rb:23:in `find_id'
        8: from /Users/kyeg_logos_mac/GitHub_Box/api-mind-map/app/domain/favorites/repositories/documents.rb:48:in `rebuild_entity'
        7: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/dry-struct-1.3.0/lib/dry/struct/class_interface.rb:265:in `new'
        6: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/dry-types-1.4.0/lib/dry/types/constructor.rb:59:in `call_unsafe'
        5: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/dry-types-1.4.0/lib/dry/types/schema.rb:62:in `call_unsafe'
        4: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/dry-types-1.4.0/lib/dry/types/schema.rb:330:in `resolve_unsafe'
        3: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/dry-types-1.4.0/lib/dry/types/schema.rb:330:in `each'
        2: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/dry-types-1.4.0/lib/dry/types/schema.rb:335:in `block in resolve_unsafe'
        1: from /Users/kyeg_logos_mac/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/dry-types-1.4.0/lib/dry/types/schema.rb:338:in `rescue in block in resolve_unsafe'
Dry::Struct::Error ([MindMap::Entity::Document.new] nil (NilClass) has invalid type for :origin_id violates constraints (type?(Integer, nil) failed))
Kyeg commented 3 years ago

I found our Suggestion & Document are different. So I changed my test data to Document, and above problem is solved:

> GITHUB_TOKEN = MindMap::App.config.GITHUB_TOKEN
> PROJECT_OWNER = 'derrxb'
> PROJECT_NAME = 'derrxb'
> PROJECT_URL = 'https://github.com/derrxb/derrxb'

> MindMap::Database::DocumentOrm.all
=> []

> html_url = MindMap::Forms::AddDocument.new.call(html_url: PROJECT_URL)
> document_made = MindMap::Service::AddDocument.new.call(html_url)

> document_made.value!
=> #<MindMap::Entity::Document id=2069 origin_id=165785822 name="derrxb" description="My space online for my photography and software development thoughts" html_url="https://github.com/derrxb/derrxb" topics=[#<MindMap::Entity::Topic id=220 name="blog" description=nil>, #<MindMap::Entity::Topic id=221 name="photography" description=nil>, #<MindMap::Entity::Topic id=222 name="portfolio" description=nil>]>

> MindMap::Database::DocumentOrm.all
+------+-----------+--------+---------------------------------------------------------+----------------------------------+---------------------------+---------------------------+
| id   | origin_id | name   | description                                             | html_url                         | created_at                | updated_at                |
+------+-----------+--------+---------------------------------------------------------+----------------------------------+---------------------------+---------------------------+
| 2069 | 165785822 | derrxb | My space online for my photography and software deve... | https://github.com/derrxb/derrxb | 2020-12-06 21:41:11 +0800 | 2020-12-06 21:41:11 +0800 |
+------+-----------+--------+---------------------------------------------------------+----------------------------------+---------------------------+---------------------------+
1 row in set

> db_document = MindMap::Repository::For.klass(MindMap::Entity::Document).find_id(2069)

> document_json = MindMap::Representer::Document.new(db_document).to_json

> puts document_json
{"origin_id":165785822,"name":"derrxb","description":"My space online for my photography and software development thoughts","html_url":"https://github.com/derrxb/derrxb","topics":[{"name":"blog"},{"name":"photography"},{"name":"portfolio"}]}
=> nil

> document = MindMap::Representer::Inbox.new(OpenStruct.new).from_json(document_json)

> document.name
=> "derrxb"

> document.description
=> "My space online for my photography and software development thoughts"
Kyeg commented 3 years ago

Other subsequent question is: should we follow this convention, and rename our route from inbox/inbox_id to inboxes/inbox_id? https://github.com/KED-2020/api-mind-map/blob/6cbd158bf95f3d344e6ed33d596d4467f24d8b12/app/application/controllers/app.rb#L35https://github.com/KED-2020/api-mind-map/blob/6cbd158bf95f3d344e6ed33d596d4467f24d8b12/app/application/controllers/app.rb#L35