Permalink
Browse files

Update Routes.AddFromAssembly Ext method to also auto-register NewAPI…

… conventional routes
  • Loading branch information...
1 parent 822d8e3 commit caefcecf2a70911dc47fe9f825fd6244891d83b8 @mythz mythz committed Jan 24, 2013
@@ -6,7 +6,9 @@
using ServiceStack.Common;
using ServiceStack.Common.Utils;
using ServiceStack.Common.Web;
+using ServiceStack.Text;
using ServiceStack.ServiceHost;
+using ServiceStack.WebHost.Endpoints;
namespace ServiceStack.ServiceInterface
{
@@ -26,71 +28,109 @@ public static class ServiceRoutesExtensions
{
foreach (Assembly assembly in assembliesWithServices)
{
- IEnumerable<Type> services =
- from t in assembly.GetExportedTypes()
- where
- !t.IsAbstract &&
- t.IsSubclassOfRawGeneric(typeof(ServiceBase<>))
- select t;
-
- foreach (Type service in services)
- {
- Type baseType = service.BaseType;
- //go up the hierarchy to the first generic base type
- while (!baseType.IsGenericType)
- {
- baseType = baseType.BaseType;
- }
+ AddOldApiRoutes(routes, assembly);
+ AddNewApiRoutes(routes, assembly);
+ }
- Type requestType = baseType.GetGenericArguments()[0];
+ return routes;
+ }
- string allowedVerbs = null; //null == All Routes
+ private static void AddNewApiRoutes(IServiceRoutes routes, Assembly assembly)
+ {
+ var services = assembly.GetExportedTypes()
+ .Where(t => !t.IsAbstract
+ && t.HasInterface(typeof(IService)));
- if (service.IsSubclassOfRawGeneric(typeof(RestServiceBase<>)))
+ foreach (Type service in services)
+ {
+ var allServiceActions = service.GetActions();
+ foreach (var requestDtoActions in allServiceActions.GroupBy(x => x.GetParameters()[0].ParameterType))
+ {
+ var requestType = requestDtoActions.Key;
+ var hasWildcard = requestDtoActions.Any(x => x.Name.EqualsIgnoreCase(ActionContext.AnyAction));
+ string allowedVerbs = null; //null == All Routes
+ if (!hasWildcard)
{
- //find overriden REST methods
var allowedMethods = new List<string>();
- if (service.GetMethod("OnGet").DeclaringType == service)
+ foreach (var action in requestDtoActions)
{
- allowedMethods.Add(HttpMethods.Get);
+ allowedMethods.Add(action.Name.ToUpper());
}
- if (service.GetMethod("OnPost").DeclaringType == service)
- {
- allowedMethods.Add(HttpMethods.Post);
- }
+ if (allowedMethods.Count == 0) continue;
+ allowedVerbs = string.Join(" ", allowedMethods.ToArray());
+ }
- if (service.GetMethod("OnPut").DeclaringType == service)
- {
- allowedMethods.Add(HttpMethods.Put);
- }
+ routes.AddRoute(requestType, allowedVerbs);
+ }
+ }
+ }
- if (service.GetMethod("OnDelete").DeclaringType == service)
- {
- allowedMethods.Add(HttpMethods.Delete);
- }
+ private static void AddOldApiRoutes(IServiceRoutes routes, Assembly assembly)
+ {
+ var services = assembly.GetExportedTypes()
+ .Where(t => !t.IsAbstract
+ && t.IsSubclassOfRawGeneric(typeof(ServiceBase<>)));
- if (service.GetMethod("OnPatch").DeclaringType == service)
- {
- allowedMethods.Add(HttpMethods.Patch);
- }
+ foreach (Type service in services)
+ {
+ Type baseType = service.BaseType;
+ //go up the hierarchy to the first generic base type
+ while (!baseType.IsGenericType)
+ {
+ baseType = baseType.BaseType;
+ }
- if (allowedMethods.Count == 0) continue;
- allowedVerbs = string.Join(" ", allowedMethods.ToArray());
+ Type requestType = baseType.GetGenericArguments()[0];
+
+ string allowedVerbs = null; //null == All Routes
+
+ if (service.IsSubclassOfRawGeneric(typeof(RestServiceBase<>)))
+ {
+ //find overriden REST methods
+ var allowedMethods = new List<string>();
+ if (service.GetMethod("OnGet").DeclaringType == service)
+ {
+ allowedMethods.Add(HttpMethods.Get);
}
- routes.Add(requestType, requestType.Name, allowedVerbs);
+ if (service.GetMethod("OnPost").DeclaringType == service)
+ {
+ allowedMethods.Add(HttpMethods.Post);
+ }
- var hasIdField = requestType.GetProperty(IdUtils.IdField) != null;
- if (hasIdField)
+ if (service.GetMethod("OnPut").DeclaringType == service)
{
- var routePath = requestType.Name + "/{" + IdUtils.IdField + "}";
- routes.Add(requestType, routePath, allowedVerbs);
+ allowedMethods.Add(HttpMethods.Put);
}
+
+ if (service.GetMethod("OnDelete").DeclaringType == service)
+ {
+ allowedMethods.Add(HttpMethods.Delete);
+ }
+
+ if (service.GetMethod("OnPatch").DeclaringType == service)
+ {
+ allowedMethods.Add(HttpMethods.Patch);
+ }
+
+ if (allowedMethods.Count == 0) continue;
+ allowedVerbs = string.Join(" ", allowedMethods.ToArray());
}
+
+ routes.AddRoute(requestType, allowedVerbs);
}
+ }
- return routes;
+ private static void AddRoute(this IServiceRoutes routes, Type requestType, string allowedVerbs)
+ {
+ routes.Add(requestType, requestType.Name, allowedVerbs);
+
+ var hasIdField = requestType.GetProperty(IdUtils.IdField) != null;
+ if (!hasIdField) return;
+
+ var routePath = requestType.Name + "/{" + IdUtils.IdField + "}";
+ routes.Add(requestType, routePath, allowedVerbs);
}
public static IServiceRoutes Add<TRequest>(this IServiceRoutes routes, string restPath, ApplyTo verbs)
@@ -248,7 +248,7 @@ public bool HasImplementation(Operation operation, Format format)
if (operation.Actions == null) return false;
return operation.Actions.Contains("POST")
- || operation.Actions.Contains("ANY");
+ || operation.Actions.Contains(ActionContext.AnyAction);
}
return true;
}
@@ -1,52 +1,105 @@
using System.Linq;
using NUnit.Framework;
-using ServiceStack.ServiceClient.Web;
using ServiceStack.ServiceInterface;
namespace ServiceStack.ServiceHost.Tests.Routes
{
- [TestFixture]
- public class ServiceRoutesTests
- {
- [Test]
- public void Can_Register_Routes_From_Assembly()
- {
- var routes = new ServiceRoutes();
- routes.AddFromAssembly(typeof(RestServiceWithAllVerbsImplemented).Assembly);
-
- RestPath restWithAllMethodsRoute =
- (from r in routes.RestPaths
- where r.Path == "RequestDto2"
- select r).FirstOrDefault();
-
- Assert.That(restWithAllMethodsRoute, Is.Not.Null);
-
- Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("GET"));
- Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("POST"));
- Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("PUT"));
- Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("DELETE"));
- Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("PATCH"));
- }
-
- [Test]
- public void Can_Register_Routes_With_Partially_Implemented_REST_Verbs()
- {
- var routes = new ServiceRoutes();
- routes.AddFromAssembly(typeof(RestServiceWithSomeVerbsImplemented).Assembly);
-
- RestPath restWithAFewMethodsRoute =
- (from r in routes.RestPaths
- where r.Path == "RequestDto"
- select r).FirstOrDefault();
-
- Assert.That(restWithAFewMethodsRoute, Is.Not.Null);
-
- Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("GET"), Is.True);
- Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("POST"), Is.False);
- Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("PUT"), Is.True);
- Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("DELETE"), Is.False);
- Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("PATCH"), Is.False);
- }
+ [TestFixture]
+ public class ServiceRoutesTests
+ {
+ [Test]
+ public void Can_Register_NewApi_Routes_From_Assembly()
+ {
+ var routes = new ServiceRoutes();
+ routes.AddFromAssembly(typeof(NewApiRestServiceWithAllVerbsImplemented).Assembly);
+
+ RestPath restWithAllMethodsRoute =
+ (from r in routes.RestPaths
+ where r.Path == "NewApiRequestDto"
+ select r).FirstOrDefault();
+
+ Assert.That(restWithAllMethodsRoute, Is.Not.Null);
+
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("GET"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("POST"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("PUT"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("DELETE"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("PATCH"));
+
+ RestPath restWithAllMethodsRoute2 =
+ (from r in routes.RestPaths
+ where r.Path == "NewApiRequestDto2"
+ select r).FirstOrDefault();
+
+ Assert.That(restWithAllMethodsRoute2, Is.Not.Null);
+
+ Assert.That(restWithAllMethodsRoute2.AllowedVerbs.Contains("GET"));
+ Assert.That(restWithAllMethodsRoute2.AllowedVerbs.Contains("POST"));
+ Assert.That(restWithAllMethodsRoute2.AllowedVerbs.Contains("PUT"));
+ Assert.That(restWithAllMethodsRoute2.AllowedVerbs.Contains("DELETE"));
+ Assert.That(restWithAllMethodsRoute2.AllowedVerbs.Contains("PATCH"));
+ }
+
+ [Test]
+ public void Can_Register_NewApi_Routes_With_Id_and_Any_Fallback_From_Assembly()
+ {
+ var routes = new ServiceRoutes();
+ routes.AddFromAssembly(typeof(NewApiRequestDtoWithIdService).Assembly);
+
+ var route = (from r in routes.RestPaths
+ where r.Path == "NewApiRequestDtoWithId"
+ select r).FirstOrDefault();
+
+ Assert.That(route, Is.Not.Null);
+ Assert.That(route.AllowedVerbs, Is.Null);
+
+ route = (from r in routes.RestPaths
+ where r.Path == "NewApiRequestDtoWithId/{Id}"
+ select r).FirstOrDefault();
+
+ Assert.That(route, Is.Not.Null);
+ Assert.That(route.AllowedVerbs, Is.Null);
+ }
+
+ [Test]
+ public void Can_Register_OldApi_Routes_From_Assembly()
+ {
+ var routes = new ServiceRoutes();
+ routes.AddFromAssembly(typeof(OldApiRestServiceWithAllVerbsImplemented).Assembly);
+
+ RestPath restWithAllMethodsRoute =
+ (from r in routes.RestPaths
+ where r.Path == "OldApiRequestDto2"
+ select r).FirstOrDefault();
+
+ Assert.That(restWithAllMethodsRoute, Is.Not.Null);
+
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("GET"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("POST"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("PUT"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("DELETE"));
+ Assert.That(restWithAllMethodsRoute.AllowedVerbs.Contains("PATCH"));
+ }
+
+ [Test]
+ public void Can_Register_OldApi_Routes_With_Partially_Implemented_REST_Verbs()
+ {
+ var routes = new ServiceRoutes();
+ routes.AddFromAssembly(typeof(OldApiRestServiceWithSomeVerbsImplemented).Assembly);
+
+ RestPath restWithAFewMethodsRoute =
+ (from r in routes.RestPaths
+ where r.Path == "OldApiRequestDto"
+ select r).FirstOrDefault();
+
+ Assert.That(restWithAFewMethodsRoute, Is.Not.Null);
+
+ Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("GET"), Is.True);
+ Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("POST"), Is.False);
+ Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("PUT"), Is.True);
+ Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("DELETE"), Is.False);
+ Assert.That(restWithAFewMethodsRoute.AllowedVerbs.Contains("PATCH"), Is.False);
+ }
[Test]
public void Can_Register_Routes_Using_Add_Extension()
@@ -56,11 +109,11 @@ public void Can_Register_Routes_Using_Add_Extension()
var route = routes.RestPaths[0];
Assert.That(route.Path == "/Users/{Name}/Orders/{OrderId}");
}
- }
+ }
- public class Customer
- {
- public string Name { get; set; }
- public int OrderId { get; set; }
- }
+ public class Customer
+ {
+ public string Name { get; set; }
+ public int OrderId { get; set; }
+ }
}
Oops, something went wrong.

0 comments on commit caefcec

Please sign in to comment.