Skip to content

Instantly share code, notes, and snippets.

@markrendle
Forked from dotnetchris/gist:3298615
Created August 8, 2012 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markrendle/3298667 to your computer and use it in GitHub Desktop.
Save markrendle/3298667 to your computer and use it in GitHub Desktop.
RESTful Simple.Web handlers
[UriTemplate("/accounts/profile/{Name}")]
[Canonical(typeof(ProfileViewModel))] // RESTful, baby!
public class GetProfile : IGet, IOutput<ProfileViewModel>
{
private readonly UserReports _userReports;
private readonly ILogger _logger;
public GetProfile(UserReports userReports, ILogger logger) // No unnecessary injections
{
_userReports = userReports;
_logger = logger;
}
public Status Get()
{
var user = _userReports.FindByName(Name);
if (user == null)
{
_logger.Write("Could not find user " + Name);
return Status.NotFound;
}
Output = DomainToPublic.Map(user, new ProfileViewModel());
return Status.OK;
}
public string Name { get; set; }
public ProfileViewModel Output { get; private set; } // Content negotiation FTMFW.
}
[UriTemplate("/accounts/profile/{Name}")]
[LinksFrom(typeof(ProfileViewModel), Rel = "update")] // Even more RESTful!
public class PutProfile : IPut, IInput<ProfileViewModel>, IOutput<IEnumerable<Exception>>, IRequireAuthentication
{
private readonly UserReports _userReports;
private readonly Func<UserService> userServiceFactory;
private readonly Func<ProfileViewModelValidator> _validatorFactory;
public PutProfile(UserReports userReports, Func<UserService> userServiceFactory, Func<ProfileViewModelValidator> validatorFactory)
{
_userReports = userReports;
_userServiceFactory = userServiceFactory;
_validatorFactory = validatorFactory;
}
public Status Put()
{
if (!(User.Name == Name || User.HasRole("Admin")))
{
return Status.Forbidden;
}
var validationResult = _validatorFactory().Validate(Input);
if (!validationResult.IsValid)
{
Output = validationResult.Errors;
return Status.BadRequest;
}
return FindAndUpdateUser();
}
private Status FindAndUpdateUser()
{
var user = _userReports.FindByName(Name);
if (user == null)
{
return Status.NotFound;
}
_userServiceFactory().Update(user.Id, user.ETag, (dbUser) => PublicToDomain.Map(Input, dbUser));
return Status.NoContent;
}
public string Name { get; set; }
public ProfileViewModel Input { get; set; }
public IEnumerable<Exception> Output { get; private set; }
public IUser User { get; set; }
}
@markrendle
Copy link
Author

This is not an exact analog of https://gist.github.com/3298615, I've taken the liberty of making some improvements along the way.

@markrendle
Copy link
Author

Note the Canonical and LinksFrom attributes, which automatically provide proper RESTful API discovery.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment