Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit 632ef41

Browse files
using new links class on index resource
1 parent 9ea7598 commit 632ef41

2 files changed

Lines changed: 100 additions & 10 deletions

File tree

src/SqlStreamStore.HAL/IndexMiddleware.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,22 @@ namespace SqlStreamStore.HAL
1212
internal static class IndexMiddleware
1313
{
1414
public static IApplicationBuilder UseIndex(this IApplicationBuilder builder)
15-
=> builder.MapWhen(IsIndex, inner => inner.Use(Index));
15+
=> builder.MapWhen(IsIndex, inner => inner.Use(Index()));
1616

1717
private static bool IsIndex(HttpContext context)
1818
=> (context.Request.Path.Value ?? "/") == "/";
1919

20-
private static MidFunc Index => (context, next) =>
20+
private static MidFunc Index()
2121
{
2222
var response = new Response(new HALResponse(null)
23-
.AddLinks(new Link(Constants.Relations.Feed, "stream"))
24-
.AddLinks(new Link(Constants.Relations.Self, string.Empty))
25-
.AddLinks(Links.Index(string.Empty))
26-
.AddLinks(Links.Find("streams/{streamId}")));
23+
.AddLinks(
24+
TheLinks
25+
.RootedAt(string.Empty)
26+
.Index().Self()
27+
.Find()
28+
.Add(Constants.Relations.Feed, "stream")));
2729

28-
return context.WriteResponse(response);
29-
};
30+
return (context, next) => context.WriteResponse(response);
31+
}
3032
}
3133
}

src/SqlStreamStore.HAL/Links.cs

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,98 @@
11
namespace SqlStreamStore.HAL
22
{
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Runtime.InteropServices;
36
using Halcyon.HAL;
47

58
internal static class Links
69
{
7-
public static Link Find(string href) => new Link(Constants.Relations.Find, href, "Find a Stream", replaceParameters: false);
8-
public static Link Index(string href) => new Link(Constants.Relations.Index, href, "Index", replaceParameters: false);
10+
public static Link Find(string href) =>
11+
new Link(Constants.Relations.Find, href, "Find a Stream", replaceParameters: false);
12+
13+
public static Link Index(string href) =>
14+
new Link(Constants.Relations.Index, href, "Index", replaceParameters: false);
15+
}
16+
17+
internal static class LinkExtensions
18+
{
19+
public static TheLinks Index(this TheLinks links) =>
20+
links.Add(Constants.Relations.Index, string.Empty, "Index");
21+
22+
public static TheLinks Find(this TheLinks links)
23+
=> links.Add(Constants.Relations.Find, "stream/{streamId}", "Find a Stream");
24+
}
25+
26+
internal class TheLinks
27+
{
28+
private readonly List<(string rel, string href, string title)> _links;
29+
private readonly string _relativePathToRoot;
30+
31+
public static TheLinks RootedAt(string relativePathToRoot) => new TheLinks(relativePathToRoot);
32+
33+
private TheLinks(string relativePathToRoot)
34+
{
35+
if(!string.IsNullOrEmpty(relativePathToRoot))
36+
{
37+
if(!relativePathToRoot.StartsWith(".."))
38+
{
39+
throw new ArgumentException("Non-empty relative path to root must start with '..'",
40+
nameof(relativePathToRoot));
41+
}
42+
43+
if(!relativePathToRoot.EndsWith("/"))
44+
{
45+
throw new ArgumentException("Non-empty relative path to root must end with '/'",
46+
nameof(relativePathToRoot));
47+
}
48+
}
49+
50+
_relativePathToRoot = relativePathToRoot ?? string.Empty;
51+
_links = new List<(string rel, string href, string title)>();
52+
}
53+
54+
public TheLinks Add(string rel, string href, string title = null)
55+
{
56+
if(rel == null)
57+
throw new ArgumentNullException(nameof(rel));
58+
if(href == null)
59+
throw new ArgumentNullException(nameof(href));
60+
61+
_links.Add((rel, href, title));
62+
return this;
63+
}
64+
65+
public TheLinks Self()
66+
{
67+
var link = _links[_links.Count - 1];
68+
69+
return Add(Constants.Relations.Self, link.href, link.title);
70+
}
71+
72+
public TheLinks AddSelf(string rel, string href, string title = null)
73+
=> Add(rel, href, title)
74+
.Add(Constants.Relations.Self, href, title);
75+
76+
public TheLinks Self(string rel)
77+
{
78+
return this;
79+
}
80+
81+
public Link[] ToHalLinks()
82+
{
83+
var links = new Link[_links.Count];
84+
85+
for(var i = 0; i < _links.Count; i++)
86+
{
87+
var (rel, href, title) = _links[i];
88+
var resolvedHref = $"{_relativePathToRoot}{href}";
89+
90+
links[i] = new Link(rel, resolvedHref, title, replaceParameters: false);
91+
}
92+
93+
return links;
94+
}
95+
96+
public static implicit operator Link[](TheLinks theLinks) => theLinks.ToHalLinks();
997
}
1098
}

0 commit comments

Comments
 (0)