Created
April 10, 2012 23:29
-
-
Save kellabyte/2355599 to your computer and use it in GitHub Desktop.
Web API ideas
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
/* | |
<?xml version='1.0' encoding='UTF-8'?> | |
<feed xmlns="http://www.w3.org/2005/Atom" | |
xmlns:as="http://atomserver.org/namespaces/1.0/" | |
xmlns:os="http://a9.com/-/spec/opensearchrss/1.1/"> | |
<os:totalResults>65801</os:totalResults> | |
<os:startIndex>0</os:startIndex> | |
<os:itemsPerPage>2</os:itemsPerPage> | |
<as:endIndex>153</as:endIndex> | |
<link href="/myserver/v1/widgets/acme?start-index=153&max-results=2" rel="next" /> | |
<link href="/myserver/v1/widgets/acme?start-index=0&max-results=2" rel="self" /> | |
<author> | |
<name>AtomServer APP Service</name> | |
</author> | |
<title type="text">acme entries</title> | |
<updated>2007-10-05T19:17:42.750Z</updated> | |
<id>tag:atomserver.org,2007:v1:acme</id> | |
<entry> | |
<id>/myserver/v1/widgets/acme/205390.en.xml</id> | |
<as:entryId>205390</as:entryId> | |
<title type="text"> Entry: acme 205390.en</title> | |
<author> | |
<name>AtomServer Atom Service</name> | |
</author> | |
<link href="/myserver/v1/widgets/acme/205390.en.xml" rel="self" /> | |
<link href="/myserver/v1/widgets/acme/205390.en.xml/2" rel="edit" /> | |
</entry> | |
</feed> | |
*/ | |
// Option 1 - AtomFormatter understands how to deal with it's own model. Feed, Entry, etc. | |
public class StoryController : ApiController | |
{ | |
public HttpResponseMessage Get(int id) | |
{ | |
Story story = GetMeAStory(id); | |
var response = new HttpResponseMessage(HttpStatusCode.OK); | |
Entry entry = ConvertToEntry(story); // Why do we need this? | |
response.Content = new ObjectContent<SyndicationItem>(entry, atomFormatter); | |
return response; | |
} | |
} | |
// I'm not convinced we need media type specific models and translate twice. Atom example: | |
// Story (our model) -> Entry (atom model) -> Atom Representation | |
// | |
// I think we can do better. | |
// Option 2 | |
var formatter = new AtomFormatter(); | |
formatter.MapModel<Story>() | |
.ToTitle(x => x.Topic) | |
.ToAuthor(x => x.Owner); | |
// Option 2b - Since Atom is specifically XML, why not use it. | |
var formatter = new AtomFormatter(); | |
formatter.MapModel<Story>() | |
.To("/feed/title", x => x.Topic) | |
.To("/feed/author/name", x => x.Owner); | |
// AtomFormatter.MapModel<T>() would return an AtomModelMap, so we still have SRP as the mapping and | |
// formatting are still independent. | |
public class StoryController : ApiController | |
{ | |
public HttpResponseMessage Get(int id) | |
{ | |
Story story = GetMeAStory(id); | |
var response = new HttpResponseMessage(HttpStatusCode.OK); | |
response.Content = this.Request.Represent(story); // The proper formatter is used based on conneg | |
return response; | |
} | |
} | |
// Option 2 and 2b don't require copying data for the purpose of mapping a translation like option 1 does. | |
// We've also eliminated a double translation that occurred in option 1. |
Given that the available transitions/links are dependent of the resource state, I'm assuming the Story
object would be responsible to know it's available transitions/links.
The formatter then would have to know how to retrieve the links from the story object in the response message. Is that correct?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@DarkSmith feel free to fork the gist and create an alternative :)
I didn't like having an intermediate model just for the purpose of translation because that forces us into translating twice. I get to use multiple formatters for a given model and map to them without having to use a model in the middle. I don't believe copying data is required to do this representation.
Please fork the gist and show the alternative. Seeing the code will be easier to understand what you mean :)