lutaml-hal 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5a918f01a4197929abfdbbdd1e061ecff5d37592ed0c880024ec11f6abe2943
4
- data.tar.gz: 032f6ba78ced7adefc4b6a9ce9c2c76acc25eba6b9d3d96398f3f09d330d312b
3
+ metadata.gz: da904351e361ae9657c850d5faf981c6b698583970ead3320f125fdf6078fcbb
4
+ data.tar.gz: 677a8d713e5c2499cd9250497ca2b6f2d9474e545a2d2b2989dbcd33802b5588
5
5
  SHA512:
6
- metadata.gz: '0802c9c05fbb34fc5a8d53a023cdd1cfda2291305b597387a5cc7afc665c9aa7eac542f03840cac494389c49442a030e79e7fdcf2169d992747e7a707fc4d9fa'
7
- data.tar.gz: 7ecabcdc778455d9d4fee7b9708c7754891ab64e3da5edb6b88927cc687806b3c5863dde63b89aa785cdcf8174c431b58fa862e0a6443e456faad13fcced0faf
6
+ metadata.gz: d1d55faaa7c1f7d45b07a3d475b6908de807f7bed3bfebdfa32ce0ada2b91a1794f948046e0e0c554216f5e18219c07ee81dfb03a2ee0f5fb19e3367821e40fb
7
+ data.tar.gz: '07085ed8d705dfe5ff1893e1c9d2ab7bc87fe3b22e483dc14edfb1b89b2e54942e21fa38f6c1ff7910030fb57c6ecf198110fa70ef8447a49c377de2935873d8'
data/README.adoc CHANGED
@@ -580,6 +580,69 @@ register.add_endpoint(
580
580
  ====
581
581
 
582
582
 
583
+ [[defining_hal_page_models]]
584
+ === Defining HAL page models
585
+
586
+ HAL index APIs often support pagination, which allows clients to retrieve a
587
+ limited number of resources at a time.
588
+
589
+ The `Lutaml::Hal::Page` class is used to handle pagination in HAL APIs. It is a
590
+ subclass of `Resource`, and provides additional attributes and methods for
591
+ handling pagination information
592
+
593
+ The `Page` class by default supports the following attributes:
594
+
595
+ `page`:: The current page number.
596
+ `pages`:: The total number of pages.
597
+ `limit`:: The number of resources per page.
598
+ `total`:: The total number of resources.
599
+
600
+ The way to use the `Page` class is through inheritance from it, where the
601
+ class will automatically create the necessary links for typical page objects.
602
+
603
+ The typical links of a page object are:
604
+
605
+ `self`:: A link to the current page.
606
+ `prev`:: A link to the previous page.
607
+ `next`:: A link to the next page.
608
+ `first`:: A link to the first page.
609
+ `last`:: A link to the last page.
610
+
611
+ The "realize class" of these links are the same as the inherited page
612
+ object, ensuring consistency in the pagination model.
613
+
614
+ Syntax:
615
+
616
+ [source,ruby]
617
+ ----
618
+ class ProductIndex < Lutaml::Hal::Page
619
+ # No attributes necessary
620
+ end
621
+
622
+ register.add_endpoint(
623
+ id: :product_index,
624
+ type: :index,
625
+ url: '/products',
626
+ model: ProductIndex
627
+ )
628
+
629
+ page_1 = register.fetch(:product_index) # Updated to use the correct endpoint id
630
+ page_2_link = page_1.links.next
631
+ # => <#ProductIndexLink href: "/products/2", title: "Next Page">
632
+ ----
633
+
634
+ Where,
635
+
636
+ `ProductIndex`:: The class of the page that will be fetched from the API. The class
637
+ must inherit from `Lutaml::Hal::Page`.
638
+ `register`:: The instance of `ModelRegister`.
639
+ `id`:: The ID of the pagination endpoint to be registered in the `ModelRegister`.
640
+ `url`:: The URL of the pagination endpoint.
641
+ `model`:: The class of the page that will be fetched from the API.
642
+
643
+
644
+
645
+
583
646
  == Usage: Runtime
584
647
 
585
648
  === General
@@ -668,9 +731,6 @@ them using the `fetch` method.
668
731
  The `fetch` method will automatically handle the URL resolution and fetch the
669
732
  resource index from the API.
670
733
 
671
- // The `Page` class is used to handle pagination and resource
672
- // resolution for collections.
673
-
674
734
  Syntax:
675
735
 
676
736
  [source,ruby]
@@ -785,51 +845,13 @@ product_2
785
845
  ----
786
846
  ====
787
847
 
788
- === Pagination
789
-
790
- HAL index APIs often support pagination, which allows clients to retrieve a
791
- limited number of resources at a time.
792
-
793
- The `Lutaml::Hal::Page` class is used to handle pagination in HAL APIs. The
794
- `Page` class itself is implemented as a `Resource`, so you can use the same
795
- methods to access the page's attributes and links.
796
-
797
- The `Page` class by default supports the following attributes:
798
-
799
- `page`:: The current page number.
800
- `pages`:: The total number of pages.
801
- `limit`:: The number of resources per page.
802
- `total`:: The total number of resources.
803
-
804
- Syntax:
805
-
806
- [source,ruby]
807
- ----
808
- class MyPage < Lutaml::Hal::Page
809
- # These are typical links given for page objects
810
- hal_link :self, key: 'self', realize_class: 'MyPage'
811
- hal_link :prev, key: 'prev', realize_class: 'MyPage'
812
- hal_link :next, key: 'next', realize_class: 'MyPage'
813
- hal_link :first, key: 'first', realize_class: 'MyPage'
814
- hal_link :last, key: 'last', realize_class: 'MyPage'
815
- end
816
-
817
- register.add_endpoint(
818
- id: :my_pages,
819
- type: :index,
820
- url: '/my_pages',
821
- model: MyPage
822
- )
823
- ----
848
+ === Handling HAL pages / pagination
824
849
 
825
- Where,
850
+ The `Lutaml::Hal::Page` class is used to handle pagination in HAL APIs.
826
851
 
827
- `MyPage`:: The class of the page that will be fetched from the API. The class
828
- must inherit from `Lutaml::Hal::Page`.
829
- `register`:: The instance of `ModelRegister`.
830
- `id`:: The ID of the pagination endpoint to be registered in the `ModelRegister`.
831
- `url`:: The URL of the pagination endpoint.
832
- `model`:: The class of the page that will be fetched from the API.
852
+ As described in <<defining_hal_page_models>>, subclassing the `Page` class
853
+ provides pagination capabilities, including the management of links to navigate
854
+ through pages of resources.
833
855
 
834
856
 
835
857
  .Usage example of the Page class
@@ -839,19 +861,15 @@ Declaration:
839
861
 
840
862
  [source,ruby]
841
863
  ----
842
- class MyPage < Lutaml::Hal::Page
843
- hal_link :self, key: 'self', realize_class: 'MyPage'
844
- hal_link :prev, key: 'prev', realize_class: 'MyPage'
845
- hal_link :next, key: 'next', realize_class: 'MyPage'
846
- hal_link :first, key: 'first', realize_class: 'MyPage'
847
- hal_link :last, key: 'last', realize_class: 'MyPage'
864
+ class ResourceIndex < Lutaml::Hal::Page
865
+ # No attribute definition necessary
848
866
  end
849
867
 
850
868
  register.add_endpoint(
851
- id: :my_pages,
869
+ id: :resource_index,
852
870
  type: :index,
853
- url: '/my_pages',
854
- model: MyPage
871
+ url: '/resources',
872
+ model: ResourceIndex
855
873
  )
856
874
  ----
857
875
 
@@ -859,32 +877,46 @@ Usage:
859
877
 
860
878
  [source,ruby]
861
879
  ----
862
- page_1 = register.fetch(:my_pages)
863
- # => client.get('/my_pages')
880
+ page_1 = register.fetch(:resource_index)
881
+ # => client.get('/resources')
864
882
  # => {
865
883
  # "page": 1,
866
884
  # "pages": 10,
867
885
  # "limit": 10,
868
886
  # "total": 100,
869
887
  # "_links": {
870
- # "self": { "href": "/my_pages" },
871
- # "next": { "href": "/my_pages/2" },
872
- # "last": { "href": "/my_pages/9" }
888
+ # "self": {
889
+ # "href": "https://api.example.com/resources?page=1&items=10"
890
+ # },
891
+ # "first": {
892
+ # "href": "https://api.example.com/resources?page=1&items=10"
893
+ # },
894
+ # "last": {
895
+ # "href": "https://api.example.com/resources?page=10&items=10"
896
+ # },
897
+ # "next": {
898
+ # "href": "https://api.example.com/resources?page=2&items=10"
899
+ # }
873
900
  # }
874
901
  # }
902
+
875
903
  page_1
876
- # => #<MyPage page: 1, pages: 10, limit: 10, total: 100,
877
- # links: #<MyPageLinks self: <MyPageLink href: "/my_pages">,
878
- # next: <MyPageLink href: "/my_pages/2">,
879
- # last: <MyPageLink href: "/my_pages/9">>>
904
+ # => #<ResourceIndex page: 1, pages: 10, limit: 10, total: 100,
905
+ # links: #<ResourceIndexLinks
906
+ # self: #<ResourceIndexLink href: "/resources?page=1&items=10">,
907
+ # next: #<ResourceIndexLink href: "/resources?page=2&items=10">,
908
+ # last: #<ResourceIndexLink href: "/resources?page=10&items=10">>>
909
+
880
910
  page_2 = page.links.next.realize(register)
881
- # => client.get('/my_pages/2')
882
- # => #<MyPage page: 2, pages: 10, limit: 10, total: 100,
883
- # links: #<MyPageLinks self: <MyPageLink href: "/my_pages/2">,
884
- # prev: <MyPageLink href: "/my_pages/1">,
885
- # next: <MyPageLink href: "/my_pages/3">,
886
- # first: <MyPageLink href: "/my_pages/1">,
887
- # last: <MyPageLink href: "/my_pages/9">>>
911
+ # => client.get('/resources?page=2&items=10')
912
+ # => #<ResourceIndex page: 2, pages: 10, limit: 10, total: 100,
913
+ # links: #<ResourceIndexLinks
914
+ # self: #<ResourceIndexLink href: "/resources?page=2&items=10">,
915
+ # prev: #<ResourceIndexLink href: "/resources?page=1&items=10">,
916
+ # next: #<ResourceIndexLink href: "/resources?page=3&items=10">,
917
+ # first: #<ResourceIndexLink href: "/resources?page=1&items=10">,
918
+ # last: #<ResourceIndexLink href: "/resources?page=10&items=10">>>,
919
+ # prev: #<ResourceIndexLink href: "/resources?page=1&items=10">>>
888
920
  ----
889
921
  ====
890
922
 
@@ -19,6 +19,19 @@ module Lutaml
19
19
  map 'pages', to: :pages
20
20
  map 'total', to: :total
21
21
  end
22
+
23
+ def self.inherited(subclass)
24
+ super
25
+
26
+ page_links_symbols = %i[self next prev first last]
27
+ subclass_name = subclass.name
28
+ subclass.class_eval do
29
+ # Define common page links
30
+ page_links_symbols.each do |link_symbol|
31
+ hal_link link_symbol, key: link_symbol.to_s, realize_class: subclass_name
32
+ end
33
+ end
34
+ end
22
35
  end
23
36
  end
24
37
  end
@@ -70,7 +70,7 @@ module Lutaml
70
70
  def get_links_class
71
71
  parent_klass_name = name.split('::')[0..-2].join('::')
72
72
  child_klass_name = "#{name.split('::').last}LinkSet"
73
- klass_name = "#{parent_klass_name}::#{child_klass_name}"
73
+ klass_name = [parent_klass_name, child_klass_name].join('::')
74
74
 
75
75
  raise unless Object.const_defined?(klass_name)
76
76
 
@@ -84,7 +84,7 @@ module Lutaml
84
84
  def create_link_set_class
85
85
  parent_klass_name = name.split('::')[0..-2].join('::')
86
86
  child_klass_name = "#{name.split('::').last}LinkSet"
87
- klass_name = "#{parent_klass_name}::#{child_klass_name}"
87
+ klass_name = [parent_klass_name, child_klass_name].join('::')
88
88
 
89
89
  # Check if the LinkSet class is already defined, return if so
90
90
  return Object.const_get(klass_name) if Object.const_defined?(klass_name)
@@ -92,9 +92,8 @@ module Lutaml
92
92
  # Define the LinkSet class dynamically as a normal Lutaml::Model class
93
93
  # since it is not a Resource
94
94
  klass = Class.new(Lutaml::Model::Serializable)
95
- Object.const_get(parent_klass_name).tap do |parent_klass|
96
- parent_klass.const_set(child_klass_name, klass)
97
- end
95
+ parent_klass = !parent_klass_name.empty? ? Object.const_get(parent_klass_name) : Object
96
+ parent_klass.const_set(child_klass_name, klass)
98
97
 
99
98
  # Define the LinkSet class with mapping inside the current class
100
99
  class_eval do
@@ -113,7 +112,7 @@ module Lutaml
113
112
  def create_link_class(realize_class_name)
114
113
  parent_klass_name = name.split('::')[0..-2].join('::')
115
114
  child_klass_name = "#{name.split('::').last}Link"
116
- klass_name = "#{parent_klass_name}::#{child_klass_name}"
115
+ klass_name = [parent_klass_name, child_klass_name].join('::')
117
116
 
118
117
  return Object.const_get(klass_name) if Object.const_defined?(klass_name)
119
118
 
@@ -122,9 +121,9 @@ module Lutaml
122
121
  # Define the link class with the specified key and class
123
122
  attribute :type, :string, default: realize_class_name
124
123
  end
125
- Object.const_get(parent_klass_name).tap do |parent_klass|
126
- parent_klass.const_set(child_klass_name, klass)
127
- end
124
+
125
+ parent_klass = !parent_klass_name.empty? ? Object.const_get(parent_klass_name) : Object
126
+ parent_klass.const_set(child_klass_name, klass)
128
127
 
129
128
  klass
130
129
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lutaml
4
4
  module Hal
5
- VERSION = '0.1.2'
5
+ VERSION = '0.1.3'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lutaml-hal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.