Generic Api - mattiasnordqvist/Web-Anchor GitHub Wiki
It's not unusual for REST-apis to have a pretty consistent way of treating CRUD-operations. Instead of writing web-anchor-apis for a bunch of different resources, you could use type parameters. Watch this.
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
[BaseLocation("api/{resource}")]
[UseGenericTypeAsURLResource]
public interface IAnyResourceApi<T>
{
[Get()]
Task<List<T>> List();
[Get("{id}")]
Task<T> Get(int id);
[Post()]
Task<T> Post(T t);
[Put()]
Task<T> Put(int id, T t);
[Delete()]
Task Delete(int id);
}
public class UseGenericTypeAsURLResourceAttribute : ParameterListTransformerAttribute
{
public override IEnumerable<Parameter> Apply(IEnumerable<Parameter> parameters, RequestTransformContext requestTransformContext)
{
foreach (var p in parameters) yield return p;
var typeValue = requestTransformContext.ApiInvocation.Method.DeclaringType.GetGenericArguments().First().Name.ToLower();
yield return Parameter.CreateRouteParameter("resource", typeValue);
}
public override void ValidateApi(Type type, MethodInfo method)
{
if (!type.GetGenericArguments().Any())
{
throw new WebAnchorException(nameof(UseGenericTypeAsURLResourceAttribute) + " can only be applied to apis with at least one type parameter.");
}
}
}
[TestFixture]
public class Tests : WebAnchorTest
{
[Test]
public void Test()
{
TestTheRequest<IAnyResourceApi<Customer>>(api => api.Get(5), m =>
{
Assert.AreEqual(HttpMethod.Get, m.Method);
Assert.AreEqual("api/customer/5", m.RequestUri.ToString());
});
}
}