An open API service indexing awesome lists of open source software.

https://github.com/letsar/doless.uritemplates

.Net Standard implementation of the URI Template Spec https://tools.ietf.org/html/rfc6570
https://github.com/letsar/doless.uritemplates

Last synced: 10 months ago
JSON representation

.Net Standard implementation of the URI Template Spec https://tools.ietf.org/html/rfc6570

Awesome Lists containing this project

README

          

# DoLess.UriTemplates

.Net Standard 1.3 implementation of the URI Template Spec [RFC6570](http://tools.ietf.org/html/rfc6570):

* Supports up to level 4 templates expression
* Tested against all test cases from [UriTemplate test suite](https://github.com/uri-templates/uritemplate-test).
* Fluent API
* .Net Standard 1.3
* Partial expand
* Fast

## Install

Install via [Nuget package](https://www.nuget.org/packages/DoLess.UriTemplates)

## Examples

Expand a URI template:

```csharp
string uriString = UriTemplate.For("http://example.org/{resource}{?genre,count}")
.WithParameter("resource", "books")
.WithParameter("genre", "sci-fi")
.WithParameter("count", 10)
.ExpandToString();
uriString.ShouldBeEquivalentTo("http://example.org/books?genre=sci-fi&count=10");
```

You can pass a string list:

```csharp
string uriString = UriTemplate.For("http://example.org/{resource}{?genre}")
.WithParameter("resource", "books")
.WithParameter("genre", "sci-fi", "horror", "fantasy")
.ExpandToString();
uriString.ShouldBeEquivalentTo("http://example.org/books?genre=sci-fi,horror,fantasy");
```

```csharp
string uriString = UriTemplate.For("http://example.org/{resource}{?genre*}")
.WithParameter("resource", "books")
.WithParameter("genre", "sci-fi", "horror", "fantasy")
.ExpandToString();
uriString.ShouldBeEquivalentTo("http://example.org/books?genre=sci-fi&genre=horror&genre=fantasy");
```

Or a string dictionary:

```csharp
Dictionary options = new Dictionary
{
["genre"] = "sci-fi",
["count"] = "10",
["author"] = "George R. R. Martin",
};

string uriString = UriTemplate.For("http://example.org/{resource}{?options*}")
.WithParameter("resource", "books")
.WithParameter("options", options)
.ExpandToString();
uriString.ShouldBeEquivalentTo("http://example.org/books?genre=sci-fi&count=10&author=George%20R.%20R.%20Martin");
```

When a parameter is not set, it simply removes it:

```csharp
string uriString = UriTemplate.For("http://example.org/{resource}{?genre,count}")
.WithParameter("resource", "books")
.WithParameter("count", 10)
.ExpandToString();
uriString.ShouldBeEquivalentTo("http://example.org/books?count=10");
```

`DoLess.UriTemplates` supports the following parameter types:

* `string`
* `IEnumerable`
* `IEnumerable`

All other types will be converted to `string` using the default value converter (which does a `Convert.ToString(value, CultureInfo.InvariantCulture)`).
You can control the way an object is formatted by providing an `IValueFormatter` or a `Func`:

```csharp
Func func = x =>
{
switch (x)
{
case Vector2 y:
return $"({y.X},{y.Y})";
default:
return x?.ToString();
}
};
Vector2 u = new Vector2(3, 4);
string uriString = UriTemplate.For("http://example.org{/vector}")
.WithParameter("vector", u)
.WithValueFormatter(func)
.ExpandToString();

uriString.ShouldBeEquivalentTo("http://example.org/%283%2C4%29");
```

## Partial Expand

`DoLess.UriTemplates` can expand partially some templates.

The following operators cannot expand partially if there are multiple values:

* Default
* Reserved
* Fragment
* Query

Example:

```csharp
string uriString = UriTemplate.For("http://example.org/{area}/news{?type,count}")
.WithParameter("count", 10)
.WithPartialExpand()
.ExpandToString();
uriString.ShouldBeEquivalentTo("http://example.org/{area}/news?count=10{&type}");
```

## Query Object

A **query object** is an object which properties are meant to be query parameters.
You can create a **query object** by subclassing the `QueryObject` abstract class:

```csharp
public class Filters : QueryObject
{
public int Year
{
get => this.Get();
set => this.Set(value);
}

public IEnumerable Genres
{
get => this.Get>();
set => this.Set>(value);
}
}

Filters filters = new Filters
{
Year = 1988,
Genres = new[] { "action", "adventure" }
};

var result = UriTemplate.For("/api{?filters*}")
.WithParameter("filters", filters)
.ExpandToString();

result.ShouldBeEquivalentTo("/api?year=1988&genres=action,adventure");

```

You can choose the way to format your property name by specifying a `Func` in the `Get` and `Set` methods.
You can also set a default format function for all your properties by calling the base constructor with a `Func` (By default it will be snake_lower_case):

```csharp
public class CustomQueryObject : QueryObject
{
public CustomQueryObject()
: base(StringFormatters.ToKebabCase)
{
}

public int KebabCase
{
get => this.Get();
set => this.Set(value);
}

public int LowerCamelCase
{
get => this.Get(StringFormatters.ToLowerCamelCase);
set => this.Set(StringFormatters.ToLowerCamelCase, value);
}

public int MyOwnFormat
{
get => this.Get(null,"WithMyOwnKey");
set => this.Set(null, value, "WithMyOwnKey");
}
}

CustomQueryObject customQueryObject = new CustomQueryObject
{
KebabCase = 1,
LowerCamelCase = 2,
MyOwnFormat = 3
};

var result = UriTemplate.For("/api{?filters*}")
.WithParameter("filters", customQueryObject)
.ExpandToString();

result.ShouldBeEquivalentTo("/api?kebab-case=1&lowerCamelCase=2&WithMyOwnKey=3");
```

`DoLess.UriTemplates` comes with default formatters, available in `DoLess.UriTemplates.Helpers.StringFormatters`:

* `ToLowerCamelCase` (myVariableName)
* `ToUpperCamelCase` (MyVariableName)
* `ToLowerSnakeCase` (my_variable_name)
* `ToUpperSnakeCase` (My_Variable_Name)
* `ToKebabCase` (my-variable-name)
* `ToTrainCase` (My-Variable-Name)