Created
October 11, 2011 23:02
-
-
Save JasonOffutt/1279738 to your computer and use it in GitHub Desktop.
WCF REST Service API proposal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.ServiceModel; | |
using System.ServiceModel.Web; | |
using Rock.Models.Crm; | |
[ServiceContract] | |
public interface IPersonService | |
{ | |
/// <summary> | |
/// 'GET' /api/v1/people.json | |
/// </summary> | |
/// <returns>A list of people</returns> | |
[OperationContract] | |
[WebInvoke(Method = "GET", UriTemplate = "v1/people.{format}")] | |
IEnumerable<Person> List(); | |
/// <summary> | |
/// 'GET' /api/v1/people/1.json | |
/// </summary> | |
/// <param name="id"></param> | |
/// <returns>A person</returns> | |
[OperationContract] | |
[WebInvoke(Method = "GET", UriTemplate = "v1/people/{id}.{format}")] | |
Person Show(int id = -1); | |
/// <summary> | |
/// 'POST' /api/v1/people | |
/// </summary> | |
/// <param name="person">Hash of the person to be created</param> | |
/// <returns>True of false based on successful person creation</returns> | |
[OperationContract] | |
[WebInvoke(Method = "POST", UriTemplate = "v1/people.{format}")] | |
bool Create(Person person); | |
/// <summary> | |
/// 'PUT' /api/v1/people/1 | |
/// </summary> | |
/// <param name="person">Hash of the person to update</param> | |
/// <param name="id">ID of the person to update</param> | |
/// <returns>True or false based on successful person update</returns> | |
[OperationContract] | |
[WebInvoke(Method = "PUT", UriTemplate = "v1/people/{id}.{format}")] | |
bool Update(Person person, int id = -1); | |
/// <summary> | |
/// 'DELETE' /api/v1/people/1 | |
/// </summary> | |
/// <param name="id">ID of the person to delete</param> | |
/// <returns>True or false based on successful person delete</returns> | |
[OperationContract] | |
[WebInvoke(Method = "DELETE", UriTemplate = "v1/people/{id}.{format}")] | |
bool Destroy(int id = -1); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.ServiceModel; | |
using System.ServiceModel.Web; | |
using System.Web.Security; | |
using Rock.Helpers; | |
using Rock.Models.Crm; | |
public class PersonService : IPersonService | |
{ | |
private readonly bool isAuthenticated; | |
private readonly MembershipUser currentUser; | |
public PersonService() | |
{ | |
currentUser = Membership.GetUser(); | |
isAuthenticated = currentUser != null; | |
} | |
public IEnumerable<Person> List() | |
{ | |
VerifyAuthentication(); | |
using (var uow = new UnitOfWorkScope()) | |
{ | |
uow.objectContext.Configuration.ProxyCreationEnabled = false; | |
var personService = new Rock.Services.Crm.PersonService(); | |
return personService.Queryable().Where(p => p.Authorized("View", currentUser)); | |
} | |
} | |
public Person Show(int id = -1) | |
{ | |
VerifyAuthentication(); | |
using (var uow = new UnitOfWorkScope()) | |
{ | |
uow.objectContext.Configuration.ProxyCreationEnabled = false; | |
var personService = new Rock.Services.Crm.PersonService(); | |
var person = personService.GetPerson(id); | |
if (person.Authorized("View", currentUser)) | |
{ | |
return person; | |
} | |
throw new FaultException("Unauthorized"); | |
} | |
} | |
public bool Create(Person person) | |
{ | |
VerifyAuthentication(); | |
using (var uow = new UnitOfWorkScope()) | |
{ | |
var ctx = WebOperationContext.Current; | |
try | |
{ | |
uow.objectContext.Configuration.ProxyCreationEnabled = false; | |
var personService = new Rock.Services.Crm.PersonService(); | |
personService.AttachPerson(person); | |
personService.Save(person, (int)currentUser.ProviderUserKey); | |
return true; | |
} | |
catch | |
{ | |
ctx.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError; | |
return false; | |
} | |
} | |
} | |
public bool Update(Person person, int id = -1) | |
{ | |
VerifyAuthentication(); | |
using (var uow = new UnitOfWorkScope()) | |
{ | |
var ctx = WebOperationContext.Current; | |
try | |
{ | |
uow.objectContext.Configuration.ProxyCreationEnabled = false; | |
var personService = new Rock.Services.Crm.PersonService(); | |
var existingPerson = personService.GetPerson(id); | |
if (existingPerson == null) | |
{ | |
ctx.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; | |
return false; | |
} | |
if (existingPerson.Authorized("Edit", currentUser)) | |
{ | |
uow.objectContext.Entry(existingPerson).CurrentValues.SetValues(person); | |
personService.Save(existingPerson, (int)currentUser.ProviderUserKey); | |
} | |
else | |
{ | |
ctx.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; | |
return false; | |
} | |
return true; | |
} | |
catch (Exception) | |
{ | |
ctx.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError; | |
return false; | |
} | |
} | |
} | |
public bool Destroy(int id = -1) | |
{ | |
VerifyAuthentication(); | |
using (var uow = new UnitOfWorkScope()) | |
{ | |
var ctx = WebOperationContext.Current; | |
try | |
{ | |
uow.objectContext.Configuration.ProxyCreationEnabled = false; | |
var personService = new Rock.Services.Crm.PersonService(); | |
var person = personService.GetPerson(id); | |
if (person == null) | |
{ | |
ctx.OutgoingResponse.StatusCode = HttpStatusCode.NotFound; | |
return false; | |
} | |
if (person.Authorized("Edit", currentUser)) | |
{ | |
personService.DeletePerson(person); | |
return true; | |
} | |
ctx.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden; | |
return false; | |
} | |
catch (Exception) | |
{ | |
ctx.OutgoingResponse.StatusCode = HttpStatusCode.InternalServerError; | |
return false; | |
} | |
} | |
} | |
private void VerifyAuthentication() | |
{ | |
if (isAuthenticated) | |
{ | |
// TODO: Consider returning a 401 (unauthenticated) or 403 (forbidden) rather than throwing an exception | |
throw new FaultException("Must be logged in"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
OK, update time.
I've hit a bit of a snag. It seems WCF doesn't offer a very good means of dynamically setting up endpoints. You still have to enter each service individually into the web.config. I'll post another Gist with what I've got so far, so you guys can see what I've been doing.