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 +4 -4
- data/README.adoc +103 -71
- data/lib/lutaml/hal/page.rb +13 -0
- data/lib/lutaml/hal/resource.rb +8 -9
- data/lib/lutaml/hal/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da904351e361ae9657c850d5faf981c6b698583970ead3320f125fdf6078fcbb
|
4
|
+
data.tar.gz: 677a8d713e5c2499cd9250497ca2b6f2d9474e545a2d2b2989dbcd33802b5588
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
===
|
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
|
-
|
850
|
+
The `Lutaml::Hal::Page` class is used to handle pagination in HAL APIs.
|
826
851
|
|
827
|
-
|
828
|
-
|
829
|
-
|
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
|
843
|
-
|
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: :
|
869
|
+
id: :resource_index,
|
852
870
|
type: :index,
|
853
|
-
url: '/
|
854
|
-
model:
|
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(:
|
863
|
-
# => client.get('/
|
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": {
|
871
|
-
#
|
872
|
-
#
|
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
|
-
# => #<
|
877
|
-
# links: #<
|
878
|
-
#
|
879
|
-
#
|
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('/
|
882
|
-
# => #<
|
883
|
-
# links: #<
|
884
|
-
#
|
885
|
-
#
|
886
|
-
#
|
887
|
-
#
|
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
|
|
data/lib/lutaml/hal/page.rb
CHANGED
@@ -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
|
data/lib/lutaml/hal/resource.rb
CHANGED
@@ -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 =
|
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 =
|
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)
|
96
|
-
|
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 =
|
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
|
-
|
126
|
-
|
127
|
-
|
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
|
data/lib/lutaml/hal/version.rb
CHANGED