-
Notifications
You must be signed in to change notification settings - Fork 8
Generic Api
Mattias Nordqvist edited this page Jun 25, 2018
·
2 revisions
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());
});
}
}
- Getting started
- Basics (Http GET & Base Location)
- Basics pt. 2 (POST/PUT/DELETE, HttpResponseMessage, Exceptions, HttpClient, IDisposable)
- Building an HttpRequestMessage
- Parameter attributes
- Handling responses
- ApiSettings
- Typical setup (Develop/Test/Production & Mocking)
- Logging
- Testing
- Generic Api
- Multipart