The WebDD community-driven conference registration is open, go ahead and book yourself for a day of fun and web technology!
You can have a look at the schedule at http://developerdeveloperdeveloper.com/webdd09/Schedule.aspx
This is not a leadership blog, please kindly piss off.
The WebDD community-driven conference registration is open, go ahead and book yourself for a day of fun and web technology!
You can have a look at the schedule at http://developerdeveloperdeveloper.com/webdd09/Schedule.aspx
This entry may be outdated. For the latest updates on openrasta, see www.openrasta.com.
I just had an idea to clean-up my resource definitions. I could’ve gone straight in the OpenRasta code and add just this small additional feature I really want, but OpenRasta is all about extensibility and composition, and I’m a few days away from the beta 1 release. So I thought I’d put to test the API from the outside, and tell you a story about how to define multiple views on a resource with the WebForms Codec. I may move this entry over to the documentation part of the project later on.
--
In OpenRasta, you need to define your resources individually. A resource in OpenRasta is simply a class you create that handlers will deal with. Each resource may have any number of URIs, and any numbers of codecs. A codec is a piece of code responsible for rendering a codec, and on this project I use the WebForms codec.
ResourceSpace.Has.ResourcesOfType<UserRegistration>()
.AtUri("/registration")
.HandledBy<UserHandler>()
.AndRendededByAspx("~/Views/User/New.aspx");
You can see here the registration for my UserRegistration resource. It defines where to find it, what handler is using it, and a page to render it.
Whenever a user has successfully registered, it’s quite usual to return them to a page welcoming them to the world of splendor that you’ll provide them, now that you have all their previous personal details. And it usually contains the exact same information that you collected previously. And that’s where it can become a bit hairy.
The initial (and in many scenario sane) reaction is to create a separate resource / handler / view couple to render our Thanks page. This is indeed accurate: the thing that I serve to the client is indeed a document with a “Thank you” message, complete with blink tags.
Another point of view, and the one I usually favour, is to consider those various elements as different views on the same resource. From a ReST point of view, each of those views will be a resource in its own right, but from a programming perspective OpenRasta will treat them as being the same entity to operate against.
So how do we solve the conundrum? The first piece of the puzzle is to use the capacity baked in the WebForms view engine to define multiple views. We can change the registration ever-so-slightly by using the generic notation for registering the view.
ResourceSpace.Has.ResourcesOfType<UserRegistration>()
.AtUri("/registration")
.HandledBy<UserHandler>()
.AndTranscodedBy<WebFormsCodec>(new
{
index = "~/Views/User/New.aspx",
thanks= "~/Views/User/Thanks.aspx"
});
The registration looks very similar. The AndRenderedByAspx method you saw earlier is a shorthand for the full notation using the AndTranscodedBy<T> which lets you plug-in many different codecs per-resource.
The anonymous type itself defines view names that will be passed to the WebForms codec. The question is, how do we get the framework to choose those views?
By default, that codec always uses a view named index (or default or get) for the default view to select. Another approach is to use uri path segments. If I typed the URI http://localhost/registration;thanks the thanks bit is called a path segment, and is always separated by a semi-column. If you go and try that now on your OpenRasta website, it won’t work (something about not enabling features don’t want). You need to go and enable it by adding a UriDecorator.
ResourceSpace.Has.UriDecorator<PathSegmentAsRendererUriDecorator>();
URI decorators in OpenRasta are modules that lets you manipulate uris before a request is processed. It’s used for integrating various features, such as file extensions, localized URIs, and whatever else you may think of. And the reason the PathSegmentAsRenderer is called the way it is is historical, and before this blog entry I never realized that it should really be updated to PathSegmentAsCodecParameter. Expect to see that change in the trunk over the weekend. (Codecs used to be called Renderers when I was working on the codebase that preceded OpenRasta).
So, all is good, we can now go to /registration;thanks and see the Thanks.aspx page rendering a resource. But what if you didn’t want to use path segments, and define two different URIs yourself?
.AtUri("/registration")
.AndAt("/registration/{emailAddress}/complete").Named("thanks")
.HandledBy<UserHandler>()
.AndTranscodedBy<WebFormsCodec>(new
{
index = "~/Views/User/New.aspx",
thanks= "~/Views/User/Thanks.aspx"
});
We’re going to need to leverage a few other features of the configuration API.
First is the support for named URIs. If one resource can have multiple name, that feature lets you give it a friendly name. It is mostly used to decorate a handler method to help select which overload of a method gets executed, but it can also serve our purpose here quite well.
We’re going to plug in the OpenRasta pipeline, and do the same thing the PathSegmentAsRendererUriDecorator type does: add a string that will be sent to the codec to help it choose. To do this, we’re going to implement a class implementing IPipelineContributor. You can find the code at the end, as an example.
This exposes a few specificities of OpenRasta. The first one is the pipeline model itself. Whenever you want to integrate deep within the framework, and modify the way things are processed, you need to tell OpenRasta which components you depend on in the execution pipeline. That’s what the ExecuteBefore and ExecuteAfter methods do. Out of the box, there’s 18 contributos to choose from. Each component does a tiny bit of the request processing, and enrich the data until it’s been turned back into a byte stream. The execution order is non-deterministic: OpenRasta will always honour your requests to be before or after someone else, but doesn’t guarantee anything beyond that.
Another aspect is the fact that pipeline contributors are the only components in the system to be singletons. They will be loaded one and never be discarded. That’s why they take a dependency on the ICommunicationContext god object. It’s the only ever Context object you’ll find in OpenRasta. Most of the interfaces in the system have flat methods with a well-known number of parameters. Just the minimum amount of information needed for a component to execute, everything else is handled by dependency injection.
Overall, when you’re an IPipelineContributor in OpenRasta, your’re like god, you run at the kernel of stuff. And because it’s a pipeline model, any of your actions *will* have consequences on everyone else. There’s many other less low-level extensibility points in OpenRasta, so when you can, use them!
The code
public class UriNameAsCodecParameter : IPipelineContributor
{
public void Initialize(IPipeline pipelineRunner)
{
pipelineRunner.ExecuteBefore<ResponseEntityWriter>(AddUriNameToCodecParameters);
}
public PipelineContinuation AddUriNameToCodecParameters(ICommunicationContext context)
{
if (context.PipelineData.SelectedResource.UriName != null)
{
var newCodecParameters = new List<string> { context.PipelineData.SelectedResource.UriName };
if (context.Request.CodecUriParameters != null)
newCodecParameters.AddRange(context.Request.CodecUriParameters);
context.Request.CodecUriParameters = newCodecParameters.ToArray();
}
return PipelineContinuation.Continue;
}
}
The registration (until I’ve revisited that part of the code, cause I sure don’t like it. It’s an outstanding task)
DependencyManager.GetService<ITypeRepository<IPipelineContributor>>().Types.Add(typeof(UriNameAsCodecParameter));
I’m not going to do yet another intro, the event detail is on http://ukdotnet.ning.com/events/altnet-london-beers-7
The place, same as usual, same people, Tequila\UK and ThoughtWorks helping us. Lots of brains, some beer, and many many opinions.
Please register if you can, it’s not mandatory but it’s useful to gauge the amount of people we’re going to get!
Conversation has continued in the comments, and I think it's going in the right direction. But then Anthony takes offense to the fact that I call out to Jason on my blog.
I'm engaging the conversation through my blog because not everyone is on twitter, and not everyone is on mailing lists. I can safely say that the majority of the alt.net regulars in London are not even subscribed to any mailing list. By bringing the conversation outside of the echo chamber silos that exist in mailing lists and twitter, we get more point of views and that helps me understand things better.
Which was also a reason for posting. I genuinely dont get it. It's either just a manifesto showing intent, or it's much more and that much more I've yet to hear about.
I raised two things in my post: the first on the fundamentals of craftsmanship, the second on community involvement. On the former, the discussion has started and Cory has raised points that make very much sense to me. I'll be bringing more of that conversation on the craftsmanship mailing list, and see what happens there.
The second fundamental is the one of community engagement. I called on Jason on my blog because I assumed he was involved in the Software Craftsmanship movement, having organized a conference bearing the name, and both being presented together on the wikipedia page mentioned in a recent message on the craftsmanship mailing list.
From that assumption, I made an additional one: if you put your time in organizing a conference about something, you want to see this something go forward and you go out there to discuss what it is and why it's important.
And I made a final assumption: any new community grows by having ties with existing one. You embrace and extend. Otherwise communities grow in a silo.
On the first assumption, apparently the only relationship is the book and the wikipedia page, and Jason has said he was not in the job of convincing me or anyone else, he was just a signatory supporting them (Did I understand it correctly this time?).
By extension the second assumption also collapses and someone else may have to come and take up on that offer to come and talk software craftmanship at one of our meetings. And the third assumption is my own opinion on community building, still stands but has no value now that the other two collapsed.
The thing is, with Jason proposing a regular meeting around the topic of Software Craftmanship, and with the focus the alt.net Beers has had so far, our event would become completely redundant and unnecessary. And I'd be quite glad if that happened But if no one comes and engage us, and if my attemps at engaging fail, it's just not going to happen.
So, Anthony... I really don't engage your brother for the sake of it, I engage him beacuse I assumed his involvement was more than it was, and because my few messages to him on twitter have either received no response or responses that were not educational. By blogging it, Jason has responded, points have been cleared and we can move forward in the conversation. So overall I know more now than I did then.
And finally, I haven't belittled the conference in any way. I'm sure it was a very successful one, and people seemed happy enough blogging about it. But I am very surprised it hasn't been broadcasted much in my neck of the wood, even though one of the guys helping organize (Gojko) is *definitly* in my neck of the wood. Why? I'm not sure. But if the intent is to grow and learn, then there could've been more outreach to existing communities.
I don't think I have trolled or attacked anyone personally. I'm just profoundly confused by the why, and the apparent disinterest in involving and engaging existing technical communities.
And I could've answered that on your blog, Anthony, if the comments were not disabled. But at least that'll clear-up my personal rules of engagement when it comes to communities, bloggers and the twitteristas.
[Update: Jason has responded in the comments that he was not responsible for teaching or convincing me of the values of the software craftsmanship movement. If anyone in London is interested, I extend the invitation to come and talk about software craftsmanship with the rest of the alt.net community. Don’t hesitate to email me.]
There is a slight breeze coming from a corner of the software development world. The software craftsmanship community has released a manifesto.
I’m not signing it yet. I’ve read the mailing list, I’ve read the manifesto, I chatted with people on messenger, and I still can’t figure out what the objectives of the manifesto are. And the few questions I have or had have not been answered.
Mark was kind enough, on twitter, to explain to me that it was about creating awareness that there is a problem with the current state of software development. Of course I couldn’t agree more with that statement. After all, this is one of the things that the alt.net communities have been focusing on a lot lately (as in, in the last year).
But just like the post-agile thing I never really understood, I don’t understand how this has much relevance beyond making a statement. I value the craft, but I do not believe that my craft, which is of a different category from what some developers do for a living, is necessary all the time.
Then I have an issue with the word craft, because it is always being opposed to the word mass production. But there is no such split in the software world. Any historical effort to turn development in mass production has failed (4GLs, software factories, etc). It never happened and it never will, and as such I do not see it as a positive outcome to encourage people in making the distinction.
The other thing that I’m confused about is that, while London had a Software Craftsmanship conference organized by Jason Gorman, I have not heard about any of this till very recently, nearly by accident. A search on the alt.net mailing list has triggered no apparent results. I only heard talks about it from one ex-BBC at the alt.net Beers, once. Nothing at KaizenConf. So it comes a bit out of the blue. So I invited Jason Gorman to the alt.net beers a couple of times, without a response. Let me reformulate the invite once more on this blog. Jason, come and explain to us why Software Craftsmanship is important and why we should care about the manifesto. I’ll even give a theme to the evening so we can discuss it for the full hour.
Finally, there are scents of local optima in the air. What is the value of the craft beyond the value brought to the customer? What is the value of becoming better locally, in our approaches to software development, when the rest of the organizational structure is left to its own progression? Indeed, Markus Gaertner proposes the following on the mailing list:
While our highest priority is to satisfy the customer through early and
continuous delivery of valuable software, our second-highest priority is to
write well-crafted code to do so.
And that’s where I seem to differ with the current trend. I don’t believe in the value of changing the software practices as a separate priority from the one of satisfying the business in generating value.
We do software that is well designed and changeable because they let us react faster to the business changing needs, and minimize costs of maintenance in the process. And knowledge and practices only exist to support those needs.
Without the business needing us to help it generate profit, there is no value in our craft. None. Nada. Zip. And when you start decoupling our needs as craftsmen from the needs of the people relying on us, you risk falling in the trap of early optimization and local optima.
So if you have a better understanding of it all, and I missed the point, please explain, I’m a willing learner.
Every organization goes through a stage in its life where boundaries between teams start appearing: developers do the development, infrastructure handles the admin, testers do the testing, etc.
With the specialization comes a redefining and splitting of responsibilities. And time and time again, the whole process comes with a corporate exercise of wall-building between teams: you need release documents, you need a UAT phase, you need to fill this form here or request that deployment there.
In itself, a more structured communication is not an issue, quite the contrary. Generating artefacts in a project to describe processes that cross teams is an important step to take in ensuring maintainability.
Where the team-splitting becomes an impediment is when teams start allocating themselves exclusive competencies: developers shouldn’t know about build scripts, release teams shouldn’t know about development, testers would build their own test scripts and not share them…
Often, teams start by holding many responsibilities. Start-ups are full of people that know everything from coding to deployment to admin. They’re not experts in any particular topic, and they may do mistakes, but they have an involvement in all parts.
As the teams grow, those skills get dissolved. And as products become larger and more complex, and as companies gain visibility, the required skills become more specialized too. Failing a deployment in a small start-up has less impact on the business than when you have signed those 4 or 5 9s contracts with a corporate client.
The immediate reaction at this point is to create a specialized team and focus the skills of team members. Those teams are now responsible for only a small part of the project lifetime, and are judged on the reliability of *their* process rather than on the project itself.
You end up in a situation where the cross-competency skills have already been dissolved because of a larger team with more specialized skills, and what skillsets were present have now been moved in a separate team, diminishing the spread of skills even more. Of course, this will mean that more mistakes will be done by a less-skilled team in a specific area, and the team responsible for that competency will start building walls to protect itself from the resulting unreliability.
You’re now in a situation where each team has built walls around it to enforce any phase transition through gatekeepers.
I am convinced that gatekeepers are a symptom of a wider problem in your software development lifecycle. Gatekeepers become a bottleneck, be it because of resources or because the gatekeepers usually know what’s inside the castle but have less knowledge of what is outside the castle. This is true for each competency needed to deliver a project: analysts, testers, build masters, developers, project managers…
The first step to resolve those bottlenecks is to take a courageous stance: recognize the competency of teams while preventing them from isolating themselves from the other teams.
There’s usually a lot of hidden pain, a lot of untold mistrust to resolve. Empowering teams starts by recognizing that every single person in the company *is* a skilled professional and *wants* to deliver better software. No buts allowed. You need to start addressing why you hear “those idiots have done this in that way, we can’t trust them”. Why did they do it in such way? Could it be prevented in the future? Can the chain of events that lead to the deadlock be resolved?
Once everybody has gone over their distrust for others, teams need to move from being gatekeepers to being enablers. Instead of building walls and processes, teams should be providing the tools needed by other teams to deliver. Developers provide the tool for the business to make money, analysts provide a tool to help developers understand requirements better. Testers provide the tools for developers to understand what success criteria are defined, and developers will provide testers tools to remove the manual steps involve in their job.
You do everything in your power to avoid groups becoming optimized at their job without the full chain of production being efficient. This is what avoiding local optima is all about.
Ideally, the organizational structure of a company gets changed: people work together on a per-project team. They don’t get shuffled around randomly, and they don’t get judged on metrics specific to their competency.
If a project fails, it’s the team’s responsibility. If a project succeeds, it’s thanks to the team. The project metrics are the only ones that matter. By empowering people and focusing them on project-based success metrics, you not only ensure that everyone has the same objectives, you also cross-pollinate competencies across the company.
Just a quick reminder. My some mistake of history, I’ve been asked to deliver workshops alongside Ayende, Scott Bellware, Hammet, Mike Hadlow, Ian Cooper, David Laribee and Robert Pickering. I have to admit I’m very anxious to be surrounded by such people! Anyway, it’s going to be an absolute blast and extreme experience for anyone taking part.
I’ve just been reminded that if you register before the 4th of March, the 3 days of training will cost you £525, and before the end of may £700.
So if you care about all things progressive and the great speakers that will be presenting (and me), make your way to SkillsMatter and book now!
Last week, I got given the opportunity to present OpenRasta in the European Virtual Alt.Net meeting. It was a blast, thanks to Colin and Jan for organizing it!
And you can now have a look at the screencast on vimeo. OpenRasta’s code-freeze is happening this week, which means a week or two more to document, update the site and publish the first binaries. And this will include a retake of this screencast that *actually* works at each step :)
It’s been an exciting weekend. Thanks to a few prople with webcams, those of us that weren’t in Seattle have been able to follow some of the discussions at the alt.net seattle conf and discuss about them. You can see the recordings yourself from Ben and from Scott. Makes not being in Seattle nearly bearable.
The great other news is that you have voted for my asp.net MVC best practices talk at both DDD Belfast on the 4th of April and DDD Scotland on the 2nd of May!
Here’s a recap of where I’ll be in the next few months:
There you go. June should hopefully see me going a bit more around the country. If you want me to speak at one of your user groups, hint at your UG leader ;-)
We’re going back to the original schedule of last Tuesday of the month. Here’s the excerpt from the ning site (on which you should go and register right now to let us know how many of you will be coming).
This month, TeQUILA\UK host us and ThoughtWorks will feed us! That means free pizza, thanks guys!
An hour-long timeboxed openconf-style session where the one subject being discussed will be chosen by the attendants. And of course all this in a pub environment, fueled with just enough beer to make everybody participate.
The event is from 6pm and we start at 7:30pm sharp (ish).
Hope to see you there.
There are now two DDD events you need to vote for.
I have submitted some session to the three events, so if you want to see me rant, vote for my sessions!
Following my recent analysis of the Two-Tier Service Application Guidance, the P&P group contacted me and others to ask if we’d be interested in giving a hand to fix the guidance. Contrary to what I wrote on the original analysis, it’s not a beta 2 (the AppArch guide is, but this is not part of it).
So far, it looks like three different options are going to be pursued:
That’s the current thinking. P&P has been fairly responsive and open to criticism on the document, which has been positive. There’s been a lot of discussions ar0und terminology, and I believe those discussions are important to have, because terminology is what we use to communicate with one another.
We’re working towards getting the main issues fixed, and I’m hopeful that, once this is all done, we’ll have made those documents useful and accurate. Hopefully, next time there will be an outreach before publishing a draft. I’d also rahter the word draft was used instead of beta, but that’s splitting hair so I’ll stop there :)
Dear fans and readers,
I’ve now started writing a talk entitled Top tips to ruin your agile process. It is my intent to run the audience through the worst things that could happen to a team when they implement agile.
I have a fair share of miserable failures at turning (or keeping) a team agile, but I am now asking you to help me. Everyone has failed once or more in being agile, and I hereby plead for you to give me your horror story.
Feel free to do so below, the comments can be made anonymously :)
Thanks!
[Update: What I thought was an individual funny incident was in fact for the whole internet. See the The Register article about the snafu.]
We know that the MEF guys are a bit wicked, but that they would distribute malware is way over the top. If you don’t believe me, look what Google just showed me.
Received in my inbox today from an ex-colleague. This made me smile.
Subject: ARGH THE FUCKIN ENTITY FRAMEWORK!
Received: 29 January 2009What a load of s******t
Sorry had to get that off my chest...
Received: 26 January 2009 11:27
Lead Dev - "Oh it's really good you just drag and drop your tables on and it creates all your classes for you"
N - "F********* OFF"
Received: 26 January 2009 13:08
Just spent the last 2.5 hours hand editing some XML. Probably due to a bug in the "designer" but who knows.
Bring back NHibernate :-(
No comment.
Microsoft has released a beta version of a guidance talking about REST in 2-tier applications. I’ve had many rants about Microsoft’s attitude towards REST and the marketing branding they put on (some teams being much worse than others by arrogantly or unknowingly putting the word REST on the name of their framework).
This entry is no such rant, but an effort to outreach to the authors. The document has issues, but it is my belief that with the right corrections, it could be made accurate.
First thing come first, let’s talk about patterns. Here’s the definition for design pattern from Wikipedia.
A design pattern [..] is a formal way of documenting a solution to a design problem in a particular field of expertise.
From this, we would expect a pattern that is referenced or talked about to have been documented, contextual to a field of expertise and used to solve a design problem.
Let’s review what patterns are referenced from the document, as it will help us later to analyze the proposed guidance. Whenever a pattern is provided without references, I either assume the first documentation of a pattern as applying, or try, as a reader would, to google it and find what it could mean.
I assume this mean the pattern by which a URI is mapped to a component processing the request. My searching has returned an IBM article defining the router pattern as “[…] routing requests to specific pieces of business logic based on some defined criteria”. Anyone trying to search for the router pattern will be inundated with various definitions and hundreds of sub-patterns (content-based router pattern, dynamic router pattern, etc). By failing to reference which variant of a pattern is being included, and where the documentation for such pattern is located, a reader will be none the wiser. And they are, after all, looking for guidance.
The proposed fix: either reference which pattern is being talked about, or document what use you refer to.
A quick google search for “REST Entity pattern” will return only two results, the first one being the proposed guidance, and the second one being a presentation by Ganes Gunasegaran on a site called sagework, available as a pdf. That presentation does provide one slide defining the pattern as follows.
Now further detective work returns a MindTouch page defining the Entity pattern. Reading the rest of Ganes’ presentation, it becomes very obvious that the rest of the patterns he presents are just pulled out of the MindTouch REST patterns page. And reading the description of the patterns in the Microsoft document, you will also notice the exact same definitions.
We now have a documented pattern, within the correct field of expertise, aka MindTouch. However, a quick search for the use of this pattern being referenced outside of MindTouch’s web presence returns very little. Furthermore, it doesn’t define the problem it is designed to solve. I would question the validity of such a pattern.
The proposed fix: again, reference the correct pattern you intended to include to start with, and keep it’s original name. In this specific instance, also make sure that this pattern matches the definition of what a pattern is, or redefine and document such a pattern yourself (or get the original authors to do it).
This one is defined by Microsoft themselves, in the context of web services:
Implement an entity translator that transforms message data types to business types for requests and reverses the transformation for responses.
See http://en.wikipedia.org/wiki/Facade_pattern, “A facade is an object that provides a simplified interface to a larger body of code, such as a class library.” or P&P Pattlets “Provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.”
Fowler: “A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection.”
A google search on Domain Entity Pattern triggers an interesting result, from the same authors as the proposed guidance: Three-Tier Web Application Scenario. If you have a look at both, you will see that a lot of recycling between the two guidance documents has happened. Now of course, neither documents match our definition of a design pattern. An obscure page on wikipedia says that domain entities “are a super-set of Data Layer Entities or Data Transfer Objects, and may aggregate zero or more DLEs/DTOs” which I’ll consider compatible with the P&P definition. The naming is however confusing, and not widely in use.
Quick fix: If you want to use the same definition, aka “A set of objects modeled after a domain that represents the relationship between entities in the domain but do not contain behavior or rules related to the entities”, call it what the rest of the world calls them: an Anemic Data Model. If you are happy with the anti-pattern but are worried that it may reflect badly on the practices you suggest, call it a Data Model. If what you really mean is that it’s a DTO with the same definition as wikipedia, call it a DTO and change your definition to match what a DTO is.
Now that we’ve cleared out the confusion introduced by the guidance document’s use of patterns, let’s review the various layers and how they relate to REST.
The first thing that strikes me is the complete lack of any references to recognized litterature introducing REST. If you’re going to talk about an architecture, just like with a pattern, you *have* to provide the references.
Fix: Introduce REST and Roy Fielding’s PhD thesis. Provide links to well-known restafarian web-sites, such as the excellent http://restpatterns.org that provides guidance in implementing rest architectures.
In a RESTful architecture, everything is mapped as a Resource. This is the thing you want to operate upon. Anything can be a resource. For the sake of this entry, let’s imagine that I define a resource as being my computer’s hard drive, the physical hardware equipment that sits inside my laptop’s case.
To be able to operate on a resource, I need to be able to address it. And in REST, I can do so by giving it an identifier. In the case of HTTP, this is a URI. Let’s give a URI to my hard-drive: http://www.serialseb.com/harddrive/fujitsu.
If I type the Uri in my browser, said browser will send an http request to my server. The server is now responsible for knowing what the heck it is that I want. This process is called URI dereferencing. It’s a big word, but it is what it is and what the common definition is. It’s the process by which a URI is matched to a Resource.
It is assumed that a handler will be responsible for doing this dereferencing process. Once the resource has been dereferenced, it is time to do something with it, and this is what an http method such as GET or POST does. It defines the operation that is to be done against the Resource.
We now have the elements to understand what Microsoft talks about when they mention the Router idea. In their scenario, the router uses both the Identifier and the Operation to call some bit of code, commonly referred to as a handler. It is a sad fact that Microsoft chooses, in a REST document, to disregard completely the existing and meaningful descriptions of a web operation.
Let’s say that I want to add a song I just heard on the radio to my hard-drive. As you probably know, music is heard because the air between the singer’s vocal chords and my tympanic membrane vibrates. This vibration gets turned into an electrical signal and gets processed by my brain to let me make sense of the words that were transported as a vibration. When talking with a human, I would identify the song I just head as “If you seek Amy from Britney Spears”. If I talk with a computer, I may need to assign it a name too, so let’s do that. http://www.britneyspears.com/songs/ifyouseekamy.
As far as I know, my hard-drive cannot persist air vibrations to disk. We need a binary stream, because that’s what hard-drives can persist. That binary stream would probably be an mp3 downloaded from a music service. This byte stream is not the song itself (as in the air vibrating), it’s a file in binary format that my computer can process. If the song is a resource, the mp3 file is a Representation of that resource.
What this means for my adding that file to my hard drive is that to download the song, I would need an mp3 file. If I dereference the URI for the song, I may get a representation of this song as an mp3 file. I never transmit the resource itself.
This is why REST is called Representational State Transfer. Now that I have my file, when I want to add it to my hard drive, I could do a POST to http://www.serialseb.com/harddrive/fujitsu and include the Representation of the song. I have effectively changed the state of my resource (my hard drive, the physical thing) by sending it a representation (the mp3 file).
Microsoft says “In REST a resource is an object that represents a specific state”. As you can probably tell by now, my hard-drive doesn’t represent a state, it has a state because it is a resource. I changed it’s state by sending it a Representation. I didn’t sing to my hard-drive to make it persist an mp3.
Quick fix: clear-up the definition to “In REST a resource is a thing that can have state. You can change that state by performing operations on the resources through transferring representations.” You can probably make it more obvious by stipulating that you recommend your business entities to be your resources, acted upon by a representation (your DataContract).
Furthermore, remember that MindTouch’s definition of a REST entity that Microsoft has included is defined A Resource that gets modified only through PUT and DELETE.
We’ve seen that a representation has by definition no behavior, as it is only a byte stream, and cannot be operated upon. Because Microsoft has specified that their use of the word REST Entity is a representation of a resource, it becomes obvious that they have wrongly applied the pattern proposed by MindTouch, which applies to resources.
Confusing resources and representations is a common problem for people new to REST, and one Microsoft has fallen into.
Fix: Drop the Entity (REST) naming. You have misunderstood the original meaning of the pattern. What you are talking about is a Representation that you would probably advise to be a DataContract.
Finally, we reach the Entity Translator. Microsoft proposes that such a component “translate[s] between business entities and REST entities exposed by the service”. We’ve now seen that REST entities are in fact representations. What is proposed here is a component that can turn a resource (aka the business entity) into a representation (aka your DataContract).
It is not surprising then that the definition “Resources exposed by the service represent an external contract while business entities are internal to the service” is inaccurate.
Fix: “Resources exposed by the service can only be retrieved and modified through Representations, which represent an external contract”.
And indeed, translators are required to move data from one format (your representation) to another (your business entity as an object living in memory).
I won’t comment much on the architectural choices of Transaction Scripts and Facades, I have little interest in entering this debate. I will however take note of the definition of the service implementation (which, as we’ve seen, is usually called a handler):
“The service implementation is responsible for translating between external contracts and internal entities and then passing the request on to the business layer façade.”
This seems to indicate that the facade deals with external contracts, but the Entity Translator has already been introduced to deal with such a translation. This seems redundant and is probably a mistake.
Furthermore, if a business facade implements the logic of acting upon a business entity, and the translator maps between datacontracts and business entities, it would seem to me that you’d end up with an anemic service implementation. The only reason I can think of is to map Resource operations to business processes.
While I think such an infrastructure is redundant, here’s a proposed fix: “The service implementation is responsible for mapping operations on resources to business processes in your layer facade.”
I’m very confused by the proposed implementation of the business layer.
REST over http is often considered to be a Resource-Oriented architecture. The first, if not the most fundamental, design issue you will face is modeling your resources well. Like any domain modeling activity, this is not an easy process to get done right.
Provided you have thought of your architecture in terms of exposed resources, you then spend some time defining your representations, aka what goes on the wire. As we’ve seen, that will end up being your DataContract design.
There is a lot of inherent knowledge in resource instances: they have al the information you need to process your request. When I send a POST to http://www.serialseb.com/harddrives/fujitsu, the request contains the representation of the file I want to persist, the location in which to persist it. Nothing outside of that operation is required for the processing of the operation to happen.
Why then would one wrap the notion of adding a file onto a hard-drive into a message, pass it to a facade that dispatches the message, to finally get processed by an operation that reads the message to act upon data structures?
Any time you convert between various data structures, you introduce more complexity. Anytime you de-normalize and renormalize, you introduce potential bugs. The proposed solution does the following:
You have achieved absolutely nothing by having a facade. All the data that was required to dispatch the request to a business process was already in the service! You end up with an anemic service that does little if nothing, a business facade that’s not really a facade but a broker, and a business process that has to open-up the encapsulation format for no valid reason at all.
As this document is supposed to be a guidance as to best architect a solution, the proposed solution is just not acceptable. Proposing an anemic service is a symptom of a bigger problem: the guidance doesn’t talk at all about resource modeling, and assume that there will be redundant services mapping to the same business process, aka two services doing the same thing.
It looks to me as trying to slap a message oriented architecture in which the endpoint receives a message to be processed, on a resource-oriented architecture in which the endpoint is the resource on which to apply an operation. The semantics of a resource-oriented architecture eliminate the need for message dispatching.
Proposed fix: Get rid of the business facade as is, and let the service call the business process itself. The message is redundant.
Bad practice: Promote(object[] data) is just bad practice as you’ve now removed any single bit of semantics that were associated with the process.
There is a simple alternative fix that can be applied to the document, by removing the REST references and describing it as a POX architecture.
I do not know if this guidance is the result of an incomplete understanding of REST architectures (which is quite widespread in Microsoft’s literature) or an attempt at over-simplification.
What I do know is that much needs to be modified before this document can be proposed as a best practice for delivering a RESTful solution. It lacks the proper and accepted terminology, completely bypasses architectural concerns around resource modeling, misrepresent what a REST architecture would look like. It also ignores caching (one of the REST constraints) and proposes an architecture that would make leveraging such caching difficult.
I also call for P&P to involve the communities that have formed around topics such as DDD and REST when they deliver beta versions of their guidance documents. Those errors I’ve highlighted could have been taken care of much earlier in the process, and save me the 5 hours I spent this afternoon writing this blog entry. That this is considered a beta 2 is however completely unacceptable.
Hopefully we will see an updated version of this guidance. If not, hopefully my blog entry will have enough google juice to start fixing the inaccuracies that Microsoft seems to spread about REST way too often.
I’ve been following Opera’s reactions to the EU antitrust regulations against Microsoft’s bundling IE in windows, which they have been calling for…
Anyone remembers what happened last time a browser vendor tried to leverage antitrust laws to explain their sinking (or in the case of Opera, their fairly constant and unimpressive) market share? No?
Bah.
With all the festive excitements, I really thought I had announced this when I put the date down on http://ukdotnet.ning.com but I obviously didn’t.
So as (nearly) every months, we’ll be holding our monthly alt.net meeting in Soho next Monday, with tester extraordinaire and dynamic language addict Ben Hall. Please register on http://ukdotnet.ning.com/events/altnet-london-beers-5 so I know how many of you to expect. We also usually wait for everyone to have arrived before starting, and if you’re not on the list we can’t start!
The format is a mini openconf-style session. Here are the rules, slightly changed to learn from the previous event.
The location
We should be able to hold our reunion at the Tequilla lounge bar, like last time. I’ll have confirmation tomorrow, and if not I’ll announce here a new location.
As you may know, text and ntext types are being depreciated in sql server 2005+, and replaced by varchar(max) and nvarchar(max).
If like me you rely on nhibernate to generate your database, the trick for getting nvarchar(max) is to set the length of the field to 10000. I wrote a small extension method to do this.
public static class PropertyMapExtensions
{
public static PropertyMap WithMaxSize(this PropertyMap map)
{
return map.WithLengthOf(10000);
}
}
I use the automapping functionality, so this is what it then looks like.
AutoPersistenceModel.MapEntitiesFromAssemblyOf<Movie>()
.Where(t => t.Namespace == (typeof(Entity).Namespace) && !t.IsAbstract && t.IsPublic)
.ForTypesThatDeriveFrom<Movie>(x =>
{
x.Map(m => m.LongSynopsis).WithMaxSize();
x.Map(m => m.Notes).WithMaxSize();
})
.Configure(configuration);