Thursday, 7 June 2012
Stop ! Collaborate & Listen
I'm on a contract with a team where the front-end (an ASP.NET MVC) site is being written by an external company (we'll call them Websites Inc).
Webites Inc don't want to collaborate. They won't come into our offices (not even on the last week of a deliverable), they won't give us skype access or phone numbers of their developers.
I'm a contractor - I can't force my host company to get these guys to collaborate - to put the proverbial boot down as it were. To make them understand why collaboration is *so* important.
Ouch.
So I'm looking at Website Inc's code, and its not the best to be fair.
They're making some basic coding mistakes.
They're repeating themselves in code.
They're peppering their code with try/catch blocks.
They're returning different views from actions depending on whats happening.
They're wrapping stuff unnecessarily.
They're building in their own authenitcation layer (even though our api deals with it)
They're not naming controllers after resources
They're using controllers as a dumping ground for actions
etc etc etc
With a few friendly chats and discussions we could sort this stuff out really quickly.
But they won't collaborate.
So whats a chap to do ?
Well, I refactored it.
If someone refactored my code without discussing it I'd be pretty narked. I'd be pissed that they had not discussed why it was done, or why I was breaking MVC etc.
If we'd collaborated, it could have been a learning experience for both of us.
And that's the point - collaboration between software teams, and within software teams leads to cleaner, more maintainable code. Both sides learn something.
The way it is right now - no collaboration - can only lead to hurt feelings, and ruined relationships.
Its 2012. When will companies realise that collaboration & sharing leads to better software?
Monday, 7 May 2012
What is a software architect ?
I currently contracting at the moment, as a 'developer' or 'programmer'.
I applied for a role the other day that I felt was entirely within my skillset - agile, asp.net mvc, tdd.
When I called the recruitment agent, he questioned whether or not I had any recent hands-on development experience.
Which I thought was weird, because I've had over 10 years relentless development experience.
After I'd spoken to him, I realised why he'd asked - its because the last two roles on my CV had the word 'Architect' in them.
Speaking to other people, software 'architects' seem to be percieved often as people that don't code, and design systems from above - think word documents, visio diagrams and the like.
Which is weird, because I'd always thought as a 'architect' as being something different :
1) They have an overall say on the software architecture (when the team has differing opinions and someone has to make a call)
2) They involve themselves on a day-to-day basis with coding (ie pushing features and pairing)
3) They act as mentors to other devs on the team that need help
4) They act as a facilitator to external pressures on the team (ie a sh*t umbrella)
5) They act as a mediator within the team for discussions about architecture on the team
But this role, how I see an 'architect', means having a team that is :
1) Capable of pro-active discussions about software & design2) Capable of decision making, for the benefit of the team and project
3) Capable of accepting responsibility for the software (and hardware) architecture
4) Capable of being responsible for the delivery of the software
Which I guess, is where me and the recruitment agent left each other on how we define 'architect' within a company.
Being a 'software architect' was one of the hardest jobs I ever did - and also one of the most rewarding. But it certainly meant I still remember how to code.
Thursday, 19 April 2012
ASP.NET MVC4 Web API / appharbor / IIS / http status codes
You're being a good RESTful developer, and using http status codes correctly.
You're sending back 400 BadRequest when validating user input, you're using 403 when somebody does something their not allowed to do, and 401 to issue authentication required.
You're sending nice friendly, informative error messages for those 4xx responses.
And then you deploy to appharbor, which is running on IIS 7, and you're app stops sending back those nice formatted error messages.
Weird, you think ... works locally !
You spend hours trying to figure it out. And then you finally ask @appharbor, and they let you know about a crazy HttpContext setting.
What it is, is IIS7 being mental. And stomping on your response body.
What you need to do is for every response that is not 2xx or 3xx, you need to do this :
HttpContext.Current.Response.TrySkipIisCustomErrors = true;
*** UPDATE ***
Khalid (see comments below) has pointed out that you can do this in Web.config instead, which is a better. Cheers fella ! See http://blog.aquabirdconsulting.com/?p=359
Example:
<system.webserver>
<httpErrors existingResponse="PassThrough"/>
</system.webserver>
*** END UPDATE ***
But where to put it ? Well, whereever works for you.
I follow this pattern in all my controllers :
public class ExampleController : ApiController
{
public HttpResponseMessage Delete(long id)
{
return this.Try(() =>
{
_organisationService.Delete(id);
return 204.Response();
});
}
}
Where 'Try' is a method that catches known exceptions (ie can't find an entity, input is invalid etc etc)
public static HttpResponseMessage Try(this ApiController controller, Func<HttpResponseMessage> operation)
{
try
{
return operation.Invoke();
}
catch (EntityNotFoundException e)
{
return 404.Response(MessageResponse.From(e.Message));
}
catch (ForbiddenException e)
{
return 403.Response(MessageResponse.From(e.Message));
}
catch(PermissionsException e)
{
return 403.Response(MessageResponse.From(e.Message));
}
catch (ValidationException e)
{
if (e.HasMultipleErrors())
{
return 400.Response(e.Errors);
}
return 400.Response(MessageResponse.From(e.Message));
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
return 500.Response(MessageResponse.From(e.ToString()));
}
}
and I have this extension method, where I put in the magic IIS hack :
public static HttpResponseMessage<T> Response<T>(this int code, T content)
{
HttpContext.Current.Response.TrySkipIisCustomErrors = true;
switch (code)
{
case 200:
return new HttpResponseMessage<T>(content, HttpStatusCode.OK);
case 201:
return new HttpResponseMessage<T>(content, HttpStatusCode.Created);
case 204:
return new HttpResponseMessage<T>(content, HttpStatusCode.NoContent);
case 400:
return new HttpResponseMessage<T>(content, HttpStatusCode.BadRequest);
case 401:
return new HttpResponseMessage<T>(content, HttpStatusCode.Unauthorized);
case 403:
return new HttpResponseMessage<T>(content, HttpStatusCode.Forbidden);
case 404:
return new HttpResponseMessage<T>(content, HttpStatusCode.NotFound);
case 500:
return new HttpResponseMessage<T>(content, HttpStatusCode.InternalServerError);
default:
throw new Exception(string.Format("Do not understand http code {0}", code));
}
}
Thursday, 22 March 2012
Cloud Foundry / Iron Foundry app & service limits
If you're running Cloud Foundry (or Iron Foundry) locally (ie the "Micro" or MCF VMs), and you get this error when provisioning a service or application :
Error 504: Too many Services provisioned: 4, you're allowed: 4
Or
Error 601: Too many applications: 4, you're allowed: 4
Then you need to alter the config on your MCF instance.
This can be done by editing /var/vcap/jobs/cloud_controller/config/cloud_controller.yml
and altering the default values displayed below :
admin_account_capacity:
memory: 1024
app_uris: 32
services: 4
apps: 4
default_account_capacity:
memory: 512
app_uris: 8
services: 4
apps: 4
Tuesday, 13 March 2012
ASP.NET MVC4 Web API
I'm not going to do full comparison, because I've not used web api in anger yet, and I don't want to be arguing for or against either frameworks, but here is some info on how to do some of the stuff you're going to want to know if considering a move from OpenRasta to ASP.NET MVC4's Web API (or perhaps just starting out in the resful framework space and have chosen Web API).
Pipelines
One thing I love about OpenRasta is the pipeline stuff - very easy.
But I have to say, Web API's making it pretty easy too ...
Note I'm injecting in a service ... its as easy as it should be
public class MyPipelineInterceptor : System.Net.Http.MessageProcessingHandler
{
readonly ISomeService _service;
public MyPipelineInterceptor(ISomeService service)
{
_service = service;
}
protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, CancellationToken cancellationToken)
{
return request;
}
protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken)
{
return response;
}
}
Dependancy Resolution
Again pretty darned easy, and I have to say (sorry Seb), easier to inject your favourite DI framework than OpenRasta 2's.
This is using Structuremap :
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
t =>
{
try
{
return ObjectFactory.GetInstance(t);
}
catch (Exception)
{
return null;
}
},
t =>
{
try
{
return ObjectFactory.GetAllInstances(t).Cast<object>();
}
catch (Exception)
{
return new List<object>();
}
}
);
Pretty easy to configure :
GlobalConfiguration.Configuration.MessageHandlers.Add(new MyPipelineInterceptor(ObjectFactory.GetInstance<ISomeService>()));
Handlers
Handlers are minimal, and feel a lot like OpenRasta's.
Instead of OperationResult you have HttpResponseMessage.
The routing is handled automagically via a single call
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
public class ValuesHandler: ApiController
{
readonly ISomeService _someService;
public ValuesHandler(ISomeService someService)
{
_someService = someService;
}
public HttpResponseMessage Get()
{
return new HttpResponseMessage(new[] {"value1", "value2"}, HttpStatusCode.OK);
}
public HttpResponseMessage Get(int id)
{
return new HttpResponseMessage("value1", HttpStatusCode.OK);
}
public HttpResponseMessage Post(string value)
{
return new HttpResponseMessage(HttpStatusCode.Created);
}
public HttpResponseMessage Put(int id, string value)
{
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
public HttpResponseMessage Delete(int id)
{
return new HttpResponseMessage(HttpStatusCode.NoContent);
}
}
Pipeline injection
So one of the patterns we use (see https://github.com/agilex/agilex.persistence.openrasta) is injecting a repository into OpenRasta's CommunicationContext's PipelineData before any request, and disposing it after every request (kinda AOP style).
Chucking *global* resources into your pipeline is easy in Web API too ... in your interceptor (the first class in this post) :
request.Properties.Add("thing", new MyThing());
And then you can just access the properties in your handler/controller too, or on the response method on your pipeline interceptor.
So overall, pretty impressive so far.
As I said, I've not used it in anger yet, so not sure how it stacks up with trickier usuage (like complex model binding, or one-to-many route relationships - ie /users/123/orders), but to be fair, considering the model binding stuff is from asp.net mvc, and the routing is pretty similar, I'm sure it will be fine.
Sunday, 4 March 2012
Alternative to MVC Routing
It's on Nuget as "Mvc.Routing"
So instead of registering routes like this :
routes.MapRoute(
"foobar route",
"foo/{someParam}/bar",
new { controller = "Foo", action = "Bar" }
);
You can just call :
Routing.Register(typeof(MvcApplication).Assembly);
And then tag your controllers :
public class FooController : Controller
{
[Get("foo/{someParam}/bar")]
public ActionResult Bar(string someParam) {
// whatever
}
}
There are attributes for Get, Post, Put, Patch and Delete
The attributes behave like the normal HttpGet, HttpPost (etc) attributes - ie if you tag an action as Get(), then you can't post to it
You can use them in conjunction with the normal Http* attributes, for example :
public class FooController : Controller
{
[Get("foo/new")]
public ActionResult New() {
// whatever
}
[HttpPost]
public ActionResult Create(Bar bar) {
// whatever
}
}
If you don't use the HttpGet / HttpPost attributes for your actions, you can still register routes like so :
public class FooController : Controller
{
[Route("foo/{id}")]
public ActionResult View(Guid id) {
// whatever
}
[Route("foos")]
public ActionResult List() {
// whatever
}
}
Testing your routes is also pretty simple, below is an example using Mspec (Machine.Specifications) :
[Subject(typeof(TestController), "Given a test controller has marked the Index method as Get")]
public class when_registering_routes : register_route_context
{
Establish context = () =>
{
theExpectedRouteUrl = "all/routes/are/mine";
theExpectedActionName = "Index";
theExpectedControllerName = "Test";
};
Because of = () =>
{
Routing.Register(typeof(TestController).Assembly);
theRoute =
RouteTable.Routes.Select(x => x as Route).Where(x => x.Url == theExpectedRouteUrl).FirstOrDefault();
};
Behaves_likeroute_should_be_registered;
}
See the project specs here for more examples : https://github.com/benjaminkeeping/Mvc.Routing/tree/master/src/Mvc.Routing.Specs/registration
Thursday, 23 February 2012
Openrasta : Binding arrays / enumerables from form data
myarr[0]=11111&myarr[1]=22222
Then a controller that takes IEnumerable
Looks like the default binder in Openrasta behaves a bit differently. You need to format your form data like this instead :
myarr:0=11111&myarr:1=22222
This works with posting/putting arrays of objects as well (ie myarr:0.Name=Dave), aswell as being supported in posting/putting models which contain arrays within them
Friday, 27 January 2012
Nodejs, express, jade and express's app.bodyParser() (nodejs 0.6.8)
You've read the docs, and you're using app.use(express.bodyParser()) and its not working still.
You're config looks like this :
But you need it the other way round, like this :
What you've done wrong is have the bodyParser() line after the app.router line.
Make sure you put the bodyParser() line before the app.router line, and you're gravy.
Note that after a twitter exchange with the express developers, this isn't a bug, but a feature of express's middleware config - a side-effect of the flexibility of their middleware injection.
This 'fix' works for me - I'm pretty new to express, so I've no idea on the impact on other middleware you may have configured.
I'm sure after more playtime with express I'll understand why routing config blat's body parsing if done in that order.
PS - If anyone does know the answer, I'd welcome a full explanation, or link to the docs on it.
Wednesday, 25 January 2012
Nodejs Tedious Sql Server Driver and GUID / UNIQUEIDENTIFIER
Unrecognised data type 0x24 at offset 0x0009
But its OK when you pull back nvarchar's etc.
Nasty hack that works (considering js doesn't know what a GUID is anyway) :
Change :
select Id from table
to:
select convert(varchar(38) , Id) from table
and all is well.