From 55ece3d80df982573449996460ecb5c5ce92d202 Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Fri, 19 Apr 2013 17:05:28 -0700 Subject: [PATCH] Introducing Fancy.Nx --- NzbDrone.Api/NzbDrone.Api.csproj | 2 + .../QualityType/QualitySizeResource.cs | 5 +- NzbDrone.Api/REST/RestModule.cs | 89 +++++++++++++++++++ NzbDrone.Api/REST/RestResource.cs | 42 +++++++++ 4 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 NzbDrone.Api/REST/RestModule.cs create mode 100644 NzbDrone.Api/REST/RestResource.cs diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index 3d2f700d3..5d3e88e44 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -90,6 +90,8 @@ + + diff --git a/NzbDrone.Api/QualityType/QualitySizeResource.cs b/NzbDrone.Api/QualityType/QualitySizeResource.cs index 08e1a6653..f1dd33c5b 100644 --- a/NzbDrone.Api/QualityType/QualitySizeResource.cs +++ b/NzbDrone.Api/QualityType/QualitySizeResource.cs @@ -1,11 +1,10 @@ using System; -using System.Linq; +using NzbDrone.Api.REST; namespace NzbDrone.Api.QualityType { - public class QualitySizeResource + public class QualitySizeResource : RestResource { - public Int32 Id { get; set; } public String Name { get; set; } public Int32 MinSize { get; set; } public Int32 MaxSize { get; set; } diff --git a/NzbDrone.Api/REST/RestModule.cs b/NzbDrone.Api/REST/RestModule.cs new file mode 100644 index 000000000..a1b4f0ee0 --- /dev/null +++ b/NzbDrone.Api/REST/RestModule.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using Nancy; +using NzbDrone.Api.Extensions; + +namespace NzbDrone.Api.REST +{ + public abstract class RestModule : NancyModule + where TResource : RestResource, new() + { + private const string ROOT_ROUTE = "/"; + private const string ID_ROUTE = "/{id}"; + + protected RestModule() + : this(new TResource().ResourceName) + { + + } + + protected RestModule(string modulePath) + : base(modulePath) + { + Get[ROOT_ROUTE] = options => + { + EnsureImplementation(GetResourceAll); + var resource = GetResourceAll(); + return resource.AsResponse(); + }; + + Get[ID_ROUTE] = options => + { + EnsureImplementation(GetResourceById); + var resource = GetResourceById(options.Id); + return resource.AsResponse(); + }; + + Post[ROOT_ROUTE] = options => + { + EnsureImplementation(CreateResource); + var resource = CreateResource(ReadFromRequest()); + return resource.AsResponse(HttpStatusCode.Created); + }; + + Put[ROOT_ROUTE] = options => + { + EnsureImplementation(UpdateResource); + var resource = UpdateResource(ReadFromRequest()); + return resource.AsResponse(HttpStatusCode.Accepted); + }; + + Delete[ID_ROUTE] = options => + { + EnsureImplementation(DeleteResource); + DeleteResource(options.Id); + return new Response { StatusCode = HttpStatusCode.OK }; + }; + } + + protected Action DeleteResource { get; set; } + protected Func GetResourceById { get; set; } + protected Func> GetResourceAll { get; set; } + protected Func CreateResource { get; set; } + protected Func UpdateResource { get; set; } + + private void EnsureImplementation(Delegate implementation) + { + if (implementation == null) + { + throw new NotImplementedException(); + } + } + + private TResource ReadFromRequest() + { + var resource = Request.Body.FromJson(); + + if (Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase)) + { + resource.ValidateForPost(); + } + else if (Request.Method.Equals("PUT", StringComparison.InvariantCultureIgnoreCase)) + { + resource.ValidateForPut(); + } + + return resource; + } + } +} \ No newline at end of file diff --git a/NzbDrone.Api/REST/RestResource.cs b/NzbDrone.Api/REST/RestResource.cs new file mode 100644 index 000000000..5c93cea88 --- /dev/null +++ b/NzbDrone.Api/REST/RestResource.cs @@ -0,0 +1,42 @@ +using FluentValidation; + +namespace NzbDrone.Api.REST +{ + public abstract class RestResource + where T : RestResource, new() + { + + public int Id { get; set; } + + public virtual string ResourceName + { + get + { + return GetType().Name.ToLower(); + } + } + + protected AbstractValidator PostValidator { get; private set; } + protected AbstractValidator PutValidator { get; private set; } + + public RestResource() + { + PostValidator = new InlineValidator(); + PutValidator = new InlineValidator(); + + PostValidator.RuleFor(m => m.Id).Equal(0); + PutValidator.RuleFor(m => m.Id).GreaterThan(0); + } + + + public void ValidateForPost() + { + PostValidator.ValidateAndThrow((T)this); + } + + public void ValidateForPut() + { + PutValidator.ValidateAndThrow((T)this); + } + } +} \ No newline at end of file