Implemented static router with specs.

This commit is contained in:
Blake Watters
2010-07-21 10:44:07 -04:00
parent 6297d4f40d
commit e8c601ffb9
10 changed files with 210 additions and 30 deletions

View File

@@ -19,4 +19,18 @@
return [NSDictionary dictionary];
}
+ (id)newObject {
return [[self new] autorelease];
}
- (NSDictionary*)paramsForSerialization {
NSMutableDictionary* params = [NSMutableDictionary dictionary];
for (NSString* elementName in [[self class] elementToPropertyMappings]) {
NSString* propertyName = [[[self class] elementToPropertyMappings] objectForKey:elementName];
[params setValue:[self valueForKey:propertyName] forKey:elementName];
}
return [NSDictionary dictionaryWithDictionary:params];
}
@end

View File

@@ -10,22 +10,89 @@
@implementation RKStaticRouter
- (void)routeClass:(Class<RKResourceMappable>)class toPath:(NSString*)resourcePath {
// Turn class name into a string
// Add subdictionary with class name
- (id)init {
if (self = [super init]) {
_routes = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)routeClass:(Class)class toPath:(NSString*)resourcePath forMethod:(RKRequestMethod)method {
- (void)dealloc {
[_routes release];
[super dealloc];
}
- (void)routeClass:(Class)class toPath:(NSString*)resourcePath forMethodName:(NSString*)methodName {
NSString* className = NSStringFromClass(class);
if (nil == [_routes objectForKey:className]) {
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
[_routes setObject:dictionary forKey:className];
}
NSDictionary* classRoutes = [_routes objectForKey:className];
if ([classRoutes objectForKey:methodName]) {
[NSException raise:nil format:@"A route has already been registered for class '%@' and HTTP method '%@'", className, methodName];
}
[classRoutes setValue:resourcePath forKey:methodName];
}
// TODO: Should be RKStringFromRequestMethod and RKRequestMethodFromString
- (NSString*)HTTPVerbForMethod:(RKRequestMethod)method {
switch (method) {
case RKRequestMethodGET:
return @"GET";
break;
case RKRequestMethodPOST:
return @"POST";
break;
case RKRequestMethodPUT:
return @"PUT";
break;
case RKRequestMethodDELETE:
return @"DELETE";
break;
default:
return nil;
break;
}
}
// Public
- (void)routeClass:(Class<RKResourceMappable>)class toPath:(NSString*)path {
[self routeClass:class toPath:path forMethodName:@"ANY"];
}
- (void)routeClass:(Class)class toPath:(NSString*)path forMethod:(RKRequestMethod)method {
NSString* methodName = [self HTTPVerbForMethod:method];
[self routeClass:class toPath:path forMethodName:methodName];
}
#pragma mark RKRouter
- (NSString*)pathForObject:(NSObject<RKResourceMappable>*)resource method:(RKRequestMethod)method {
- (NSString*)pathForObject:(NSObject<RKResourceMappable>*)object method:(RKRequestMethod)method {
NSString* methodName = [self HTTPVerbForMethod:method];
NSString* className = NSStringFromClass([object class]);
NSDictionary* classRoutes = [_routes objectForKey:className];
NSString* path = nil;
if (path = [classRoutes objectForKey:methodName]) {
return path;
}
if (path = [classRoutes objectForKey:@"ANY"]) {
return path;
}
[NSException raise:nil format:@"Unable to find a routable path for object of type '%@' for HTTP Method '%@'", className, methodName];
return nil;
}
- (NSObject<RKRequestSerializable>*)serializationForObject:(NSObject<RKResourceMappable>*)resource method:(RKRequestMethod)method {
return nil;
- (NSObject<RKRequestSerializable>*)serializationForObject:(NSObject<RKResourceMappable>*)object method:(RKRequestMethod)method {
return [object paramsForSerialization];
}
@end

View File

@@ -44,7 +44,12 @@ typedef enum {
+ (NSDictionary*)elementToRelationshipMappings;
// TODO: Add an optional errors property. This will be populated when there are errors in the mapping.
// TODO: resourceParams/resourceAttributes?
/**
* Return a dictionary of values to be serialized for submission to a remote resource. The router
* will encode these parameters into a serialization format (form encoded, JSON, etc).
*/
- (NSDictionary*)paramsForSerialization;
@optional

View File

@@ -19,11 +19,11 @@
/**
* Returns the remote path to send requests for a given object and HTTP method
*/
- (NSString*)pathForObject:(NSObject<RKResourceMappable>*)resource method:(RKRequestMethod)method;
- (NSString*)pathForObject:(NSObject<RKResourceMappable>*)object method:(RKRequestMethod)method;
/**
* Returns a serialization of an object suitable for exchanging with a remote system
*/
- (NSObject<RKRequestSerializable>*)serializationForObject:(NSObject<RKResourceMappable>*)resource method:(RKRequestMethod)method;
- (NSObject<RKRequestSerializable>*)serializationForObject:(NSObject<RKResourceMappable>*)object method:(RKRequestMethod)method;
@end

View File

@@ -10,16 +10,17 @@
#import "RKResourceMappable.h"
@interface RKStaticRouter : NSObject <RKRouter> {
NSMutableDictionary* _routes;
}
/**
* Register a static mapping from an object class to a resource path
*/
- (void)routeClass:(Class<RKResourceMappable>)class toPath:(NSString*)resourcePath;
- (void)routeClass:(Class<RKResourceMappable>)class toPath:(NSString*)path;
/**
* Register a static mapping from an object class to a resource path for a given HTTP method
*/
- (void)routeClass:(Class<RKResourceMappable>)class toPath:(NSString*)resourcePath forMethod:(RKRequestMethod)method;
- (void)routeClass:(Class<RKResourceMappable>)class toPath:(NSString*)path forMethod:(RKRequestMethod)method;
@end