Skip to content

Commit bb19c13

Browse files
docs: add more comments
1 parent 8b7b709 commit bb19c13

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+674
-1525
lines changed

src/Orb/Core/ApiEnum.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,59 @@
55

66
namespace Orb.Core;
77

8+
/// <summary>
9+
/// A serializable and deserializable enum wrapper type that handles the possibility of values outside the
10+
/// range of known enum members.
11+
///
12+
/// <para>In most cases you don't have to worry about this type and can rely on its implicit operators to
13+
/// wrap and unwrap enum values.</para>
14+
///
15+
/// <param name="Json">
16+
/// Returns this instance's raw value.
17+
///
18+
/// <para>This is usually only useful if this instance was deserialized from data that doesn't match the
19+
/// expected type (<typeparamref name="TRaw"/>), and you want to know that value. For example, if the
20+
/// SDK is on an older version than the API, then the API may respond with new data types that the SDK is
21+
/// unaware of.</para>
22+
/// </param>
23+
/// </summary>
824
public record struct ApiEnum<TRaw, TEnum>(JsonElement Json)
925
where TEnum : struct, Enum
1026
{
27+
/// <summary>
28+
/// Returns this instance's raw <typeparamref name="TRaw"/> value.
29+
///
30+
/// <para>This is usually only useful if this instance was deserialized from data that doesn't match
31+
/// any known enum member, and you want to know that value. For example, if the SDK is on an older
32+
/// version than the API, then the API may respond with new members that the SDK is unaware of.</para>
33+
///
34+
/// <exception cref="OrbInvalidDataException">
35+
/// Thrown when this instance's raw value isn't of type <typeparamref name="TRaw"/>. Use
36+
/// <see cref="Json"/> to access the raw value.
37+
/// </exception>
38+
/// </summary>
1139
public readonly TRaw Raw() =>
1240
JsonSerializer.Deserialize<TRaw>(this.Json, ModelBase.SerializerOptions)
1341
?? throw new OrbInvalidDataException(
1442
string.Format("{0} cannot be null", nameof(this.Json))
1543
);
1644

45+
/// <summary>
46+
/// Returns an enum member corresponding to this instance's value, or <c>(TEnum)(-1)</c> if the
47+
/// class was instantiated with an unknown value.
48+
///
49+
/// <para>Use <see cref="Raw"/> to access the raw <typeparamref name="TRaw"/> value.</para>.
50+
/// </summary>
1751
public readonly TEnum Value() =>
1852
JsonSerializer.Deserialize<TEnum>(this.Json, ModelBase.SerializerOptions);
1953

54+
/// <summary>
55+
/// Verifies that this instance's raw value is a member of <typeparamref name="TEnum"/>.
56+
///
57+
/// <exception cref="OrbInvalidDataException">
58+
/// Thrown when this instance's raw value isn't a member of <typeparamref name="TEnum"/>.
59+
/// </exception>
60+
/// </summary>
2061
public readonly void Validate()
2162
{
2263
if (!Enum.IsDefined(typeof(TEnum), Value()))

src/Orb/Core/ClientOptions.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,79 @@
44

55
namespace Orb.Core;
66

7+
/// <summary>
8+
/// A class representing the SDK client configuration.
9+
/// </summary>
710
public struct ClientOptions()
811
{
12+
/// <summary>
13+
/// The default value used for <see cref="MaxRetries"/>.
14+
/// </summary>
915
public static readonly int DefaultMaxRetries = 2;
1016

17+
/// <summary>
18+
/// The default value used for <see cref="Timeout"/>.
19+
/// </summary>
1120
public static readonly TimeSpan DefaultTimeout = TimeSpan.FromMinutes(1);
1221

22+
/// <summary>
23+
/// The HTTP client to use for making requests in the SDK.
24+
/// </summary>
1325
public HttpClient HttpClient { get; set; } = new();
1426

1527
Lazy<Uri> _baseUrl = new(() =>
1628
new Uri(Environment.GetEnvironmentVariable("ORB_BASE_URL") ?? "https://api.withorb.com/v1")
1729
);
30+
31+
/// <summary>
32+
/// The base URL to use for every request.
33+
///
34+
/// <para>Defaults to the production environment: https://api.withorb.com/v1</para>
35+
/// </summary>
1836
public Uri BaseUrl
1937
{
2038
readonly get { return _baseUrl.Value; }
2139
set { _baseUrl = new(() => value); }
2240
}
2341

42+
/// <summary>
43+
/// Whether to validate every response before returning it.
44+
///
45+
/// <para>Defaults to false, which means the shape of the response will not be
46+
/// validated upfront. Instead, validation will only occur for the parts of the
47+
/// response that are accessed.</para>
48+
/// </summary>
2449
public bool ResponseValidation { get; set; } = false;
2550

51+
/// <summary>
52+
/// The maximum number of times to retry failed requests, with a short exponential backoff between requests.
53+
///
54+
/// <para>
55+
/// Only the following error types are retried:
56+
/// <list type="bullet">
57+
/// <item>Connection errors (for example, due to a network connectivity problem)</item>
58+
/// <item>408 Request Timeout</item>
59+
/// <item>409 Conflict</item>
60+
/// <item>429 Rate Limit</item>
61+
/// <item>5xx Internal</item>
62+
/// </list>
63+
/// </para>
64+
///
65+
/// <para>The API may also explicitly instruct the SDK to retry or not retry a request.</para>
66+
///
67+
/// <para>Defaults to 2 when null. Set to 0 to
68+
/// disable retries, which also ignores API instructions to retry.</para>
69+
/// </summary>
2670
public int? MaxRetries { get; set; }
2771

72+
/// <summary>
73+
/// Sets the maximum time allowed for a complete HTTP call, not including retries.
74+
///
75+
/// <para>This includes resolving DNS, connecting, writing the request body, server processing, as
76+
/// well as reading the response body.</para>
77+
///
78+
/// <para>Defaults to <c>TimeSpan.FromMinutes(1)</c> when null.</para>
79+
/// </summary>
2880
public TimeSpan? Timeout { get; set; }
2981

3082
Lazy<string> _apiKey = new(() =>

src/Orb/Core/FreezableDictionary.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Orb.Core;
1010
/// <summary>
1111
/// A dictionary that can be mutated and then frozen once no more mutations are expected.
1212
///
13-
/// <para>This is useful for allowing a dictionary to be modified by a class's `init`
13+
/// <para>This is useful for allowing a dictionary to be modified by a class's <c>init</c>
1414
/// properties, but then preventing it from being modified afterwards.</para>
1515
/// </summary>
1616
class FreezableDictionary<K, V> : IDictionary<K, V>
@@ -43,6 +43,12 @@ public FreezableDictionary(FrozenDictionary<K, V> frozen)
4343
_dictionary = frozen;
4444
}
4545

46+
/// <summary>
47+
/// Freezes this dictionary and returns a readonly view of it.
48+
///
49+
/// <para>Future calls to mutating methods on this class will throw
50+
/// <see cref="InvalidOperationException"/></para>.
51+
/// </summary>
4652
public IReadOnlyDictionary<K, V> Freeze()
4753
{
4854
if (_dictionary is FrozenDictionary<K, V> dict)
@@ -56,77 +62,92 @@ public IReadOnlyDictionary<K, V> Freeze()
5662
return dictionary;
5763
}
5864

65+
/// <inheritdoc/>
5966
public V this[K key]
6067
{
6168
get => _dictionary[key];
6269
set => _mutableDictionary[key] = value;
6370
}
6471

72+
/// <inheritdoc/>
6573
public ICollection<K> Keys
6674
{
6775
get { return _dictionary.Keys; }
6876
}
6977

78+
/// <inheritdoc/>
7079
public ICollection<V> Values
7180
{
7281
get { return _dictionary.Values; }
7382
}
7483

84+
/// <inheritdoc/>
7585
public int Count
7686
{
7787
get { return _dictionary.Count; }
7888
}
7989

90+
/// <inheritdoc/>
8091
public bool IsReadOnly
8192
{
8293
get { return _dictionary.IsReadOnly; }
8394
}
8495

96+
/// <inheritdoc/>
8597
public void Add(K key, V value)
8698
{
8799
_mutableDictionary.Add(key, value);
88100
}
89101

102+
/// <inheritdoc/>
90103
public void Add(KeyValuePair<K, V> item)
91104
{
92105
_mutableDictionary.Add(item.Key, item.Value);
93106
}
94107

108+
/// <inheritdoc/>
95109
public void Clear()
96110
{
97111
_mutableDictionary.Clear();
98112
}
99113

114+
/// <inheritdoc/>
100115
public bool Contains(KeyValuePair<K, V> item)
101116
{
102117
return _dictionary.Contains(item);
103118
}
104119

120+
/// <inheritdoc/>
105121
public bool ContainsKey(K key)
106122
{
107123
return _dictionary.ContainsKey(key);
108124
}
109125

126+
/// <inheritdoc/>
110127
public void CopyTo(KeyValuePair<K, V>[] array, int arrayIndex)
111128
{
112129
_dictionary.CopyTo(array, arrayIndex);
113130
}
114131

132+
/// <inheritdoc/>
115133
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
116134
{
117135
return _dictionary.GetEnumerator();
118136
}
119137

138+
/// <inheritdoc/>
120139
public bool Remove(K key)
121140
{
122141
return _mutableDictionary.Remove(key);
123142
}
124143

144+
/// <inheritdoc/>
125145
public bool Remove(KeyValuePair<K, V> item)
126146
{
127147
return _mutableDictionary.Remove(item.Key);
128148
}
129149

150+
/// <inheritdoc/>
130151
public bool TryGetValue(K key,
131152
#if NET
132153
[MaybeNullWhen(false)]
@@ -137,6 +158,7 @@ public bool TryGetValue(K key,
137158
return _dictionary.TryGetValue(key, out value);
138159
}
139160

161+
/// <inheritdoc/>
140162
Collections::IEnumerator Collections::IEnumerable.GetEnumerator()
141163
{
142164
return _dictionary.GetEnumerator();

src/Orb/IOrbClient.cs

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,80 @@
88
namespace Orb;
99

1010
/// <summary>
11-
/// NOTE: Do not inherit from this type outside the SDK unless you're okay with breaking
12-
/// changes in non-major versions. We may add new methods in the future that cause
13-
/// existing derived classes to break.
11+
/// A client for interacting with the Orb REST API.
12+
///
13+
/// <para>This client performs best when you create a single instance and reuse it
14+
/// for all interactions with the REST API. This is because each client holds its
15+
/// own connection pool and thread pools. Reusing connections and threads reduces
16+
/// latency and saves memory.</para>
17+
///
18+
/// <para>NOTE: Do not inherit from this type outside the SDK unless you're okay with
19+
/// breaking changes in non-major versions. We may add new methods in the future that
20+
/// cause existing derived classes to break.</para>
1421
/// </summary>
1522
public interface IOrbClient
1623
{
24+
/// <summary>
25+
/// The HTTP client to use for making requests in the SDK.
26+
/// </summary>
1727
HttpClient HttpClient { get; init; }
1828

29+
/// <summary>
30+
/// The base URL to use for every request.
31+
///
32+
/// <para>Defaults to the production environment: https://api.withorb.com/v1</para>
33+
/// </summary>
1934
Uri BaseUrl { get; init; }
2035

36+
/// <summary>
37+
/// Whether to validate every response before returning it.
38+
///
39+
/// <para>Defaults to false, which means the shape of the response will not be
40+
/// validated upfront. Instead, validation will only occur for the parts of the
41+
/// response that are accessed.</para>
42+
/// </summary>
2143
bool ResponseValidation { get; init; }
2244

45+
/// <summary>
46+
/// The maximum number of times to retry failed requests, with a short exponential backoff between requests.
47+
///
48+
/// <para>
49+
/// Only the following error types are retried:
50+
/// <list type="bullet">
51+
/// <item>Connection errors (for example, due to a network connectivity problem)</item>
52+
/// <item>408 Request Timeout</item>
53+
/// <item>409 Conflict</item>
54+
/// <item>429 Rate Limit</item>
55+
/// <item>5xx Internal</item>
56+
/// </list>
57+
/// </para>
58+
///
59+
/// <para>The API may also explicitly instruct the SDK to retry or not retry a request.</para>
60+
///
61+
/// <para>Defaults to 2 when null. Set to 0 to
62+
/// disable retries, which also ignores API instructions to retry.</para>
63+
/// </summary>
2364
int? MaxRetries { get; init; }
2465

66+
/// <summary>
67+
/// Sets the maximum time allowed for a complete HTTP call, not including retries.
68+
///
69+
/// <para>This includes resolving DNS, connecting, writing the request body, server processing, as
70+
/// well as reading the response body.</para>
71+
///
72+
/// <para>Defaults to <c>TimeSpan.FromMinutes(1)</c> when null.</para>
73+
/// </summary>
2574
TimeSpan? Timeout { get; init; }
2675

2776
string APIKey { get; init; }
2877

2978
string? WebhookSecret { get; init; }
3079

80+
/// <summary>
81+
/// Returns a view of this service with the given option modifications applied.
82+
///
83+
/// <para>The original service is not modified.</para>
84+
/// </summary>
3185
IOrbClient WithOptions(Func<ClientOptions, ClientOptions> modifier);
3286

3387
ITopLevelService TopLevel { get; }
@@ -62,6 +116,9 @@ public interface IOrbClient
62116

63117
ISubscriptionChangeService SubscriptionChanges { get; }
64118

119+
/// <summary>
120+
/// Sends a request to the Orb REST API.
121+
/// </summary>
65122
Task<HttpResponse> Execute<T>(
66123
HttpRequest<T> request,
67124
CancellationToken cancellationToken = default

0 commit comments

Comments
 (0)