Responses for batch results

What’s the best response shape for a batch request?

Depending on your design, batch requests don’t always work and need success and failure responses back from the endpoint.

Salesforce return the item and a success field in each response item:

[
  {
    "success" : true,
    "created" : true,
    "id" : "1",
    "errors" : []
  },
  {
    "success" : false,
    "created" : false,
    "id" : "2",
    "errors" : ['example error message']
  }
]

The AWS DynamoDB response returns a set of metadata, successes and failures:

{
  { 
    "ConsumedCapacity" : 100, 
    "OtherMetric" : true
  },
  { 
    "Items" : [ 
      { "Key" : "Item1" }, 
      { "Key", "Item2" }
    ]
  },     
  { 
    "Failed": [ 
      { "Key" : "Item3", "Reason" : "Value cannot be null" } 
    ]
  }
}

I prefer a third option, which takes the best of both. Return a list of ids you’ve received, so requests can be tracked. Return an array of items that were successful and another list that has failed. The failed messages get an array of reasons they have failed.

{
  "ids" : [ "item1", "item2", "item3" ],
  "success" : [ { id: "item1" }, { id: "item2" } ],
  "failed" : [ { "id": "item2", "reasons" : [ "String required" ] } ]
}

References:

Mounting and diagnosing an EC2 volume from a rescue instance

Here’s a quick way to troubleshoot logs on a failing EC2 with an attached volume.

  1. Remove the instance from any load balancers so it won’t be dropped from a healthcheck
  2. Take a snapshot of the volume you’re having trouble with
  3. Create a rescue instance in the same AWS Account and using the Ec2 Add Storage step attach a new volume which uses the snapshot you created mapped to device xvd*
  4. Start up your instance and connect remotely
  5. Using diskmgmt.msc browse and mount the drive
  6. Use file explorer to find your device and explore as a regular hard drive

Having trouble mapping your device? See Mapping Disks to Volumes on your EC2 instance for the documentation on the device names.

 

Change a blank project into a web project

© Microsoft
Project Selection in Microsoft Visual Studio ©

Whilst I was writing a WebApi OWIN tutorial, I started in an empty Solution with a blank Project and then wanted to change the blank project into a web project. There’s no way to do this via the GUI and I really wanted all the nice F5 tools. Rather than having to deploy to a website or IIS host each time, I’d rather start up a server at the press of a button. That way I can gain confidence in the startup of the app if I haven’t written tests yet.

There’s a few ways to do this:

  1. Modify the project metadata. You change the a blank solution to a web project. Visual Studio looks for the Guids that indicate the project is a web project and hooks up the tools.
  2. Create a new web project and drag all the files over to the new project. I much prefer this, as the project Guids and extra data (e.g., whether to use IIS, IIS Express and the hostname) is setup for you.

There’s a Stack Overflow around this which includes a list of the guids you can specify for the different types of Project:

On becoming AWS Certified

AWS Certified Developer Associate

There are a few reasons people take exams and try to gain professional certifications:

  • To prove to themselves they can do something
  • To add something to their CV
  • To prove to others that they once knew a few things about something
  • To get a promotion
  • To get noticed

I decided to take the AWS Certified Developer exam last week because I wanted to see what the exam was like, and it’s also part of my training budget at JustEat.

I’m happy to say I passed and I gained the basic AWS Certified Developer Associate qualification. This is the foundation level, and there are a few routes I can take to become an AWS certified professional. Amazon have recently updated their AWS Certification tracks on their site, so I’ll be following one of those.

I can recommend using some of the resources at CloudGuru.com and PluralSight.com as they lay out the topics you need to revise for better than the exam guidelines.

I’ve collected a top level set of exam subjects you need to revise for (.zip) in markdown format (.md).

BuildStuff 2014

I’ve just come back from an awesome conference in Lithuania – BuildStuff 2014.

This was the first full week remote conference I’ve been to and we had a lot of fun. We worked hard during the day, and explored the city at night.

JustEat sponsored one of the social events, and it was great to see so many familiar faces from Europe and further afield.

I don’t think I’d do a full week of conference again though unless I was particularly stuck for ideas or needing inspiration. I think twitter and other social media channels are good enough to keep up to date but I think conferences are great for socialising and are a good platform for announcements of new technologies – and sometimes you need that.

The best part of the week for me was the debugging .NET applications talk and then full day workshop by Sasha Goldshtein. I’d recommend it to any .NET developer. We worked our way through how .NET allocates, where items are stored, and onto the tools like procdump and a deep dive into Visual Studios debugging capabilities which turn out to be great once you get to grips with them.

Here’s a link to Sasha’s Build Stuff 2014 .NET Garbage Collection tips from his talk.

Here’s a link to Sasha’s Build Stuff 2014 Debugging .NET Applications Workshop on his blog on MSDN.

Leaving easyJet and starting at JustEat

It’s my final week at easyJet. I’ve worked on one of the web team now for over a year and a half – and I’ve learnt a lot.

I’ve learnt a lot about great teamwork. I’ve met a lot of great people. I’ve helped deliver real software and real features to one of the UK’s busiest e-commerce platforms.

If you were ever considering going to work for an airline, I can recommend it, though you’ll have a few challenges:

  • Massive code bases
  • Monolithic architectures
  • Giant databases with change control
  • Risk management (it’s a big website)
  • Agile Scrum slowness

Niggles aside, it’s a really great place to work. easyJet invest in themselves and their IT – after all, their tech is what got them to where they are today. There are so many people who want to push the platform forward, break it down and make it better for the future.

EasyJet has:

  • Great people
  • Great teamwork ethics
  • So much scope for change!
  • So many different and exciting challenges
  • Investment and opportunities

I’m sad to leave easyJet and Team Koi. I’ve made friends for life there, and know the door is open if I want to return in the future.

My next role is as a Senior .NET Developer at JustEat.co.uk – a very exciting role on a very fast moving platform – and I’m really looking forward to the challenge.

I’m wishing all the guys at easyJet the very best for the future.

 

easyJet Recent Searches

Recent Searches Screenshot
Recent Searches

Last night we re-released Release 87 of the easyJet.com booking funnel and we’re pretty happy with it. My team delivered the Recent Searches panel at the front of the site – and there are lots of other changes too.

Recent Searches will remember up to four of your searches – either from the homepage, or when you are using the flight grid – and populate this panel for you. #

It’s fully accessible (to WCAG standard A) and supports tab ordering for those who prefer navigation by keyboard only.

MVC API Routes by Type in C#

In MVC 3 onwards you can constrain routes based on your own rules.

MVC’s default API route is /api/{action}/{id} and uses the controller and action based on the controller name and HTTP Verb.

I wanted a way to route anything with /api/version/<controller> to a specific collection of controllers, based on a naming convention of my choice. I decided to use a constraint based on interfaces, but you could implement the match using Regex or any number ways. As long as you implement a IRouteConstraint you can decide your own route logic.

Lets create an empty interface which we’ll use a flag. We only want the route to apply for an API controller that implements this interface.

public interface IVersionApi
{ }

Here’s an example of one of our API controllers which implements our IVersionAPI. Note this class implements the IVersionAPI interface.
This will be hit when I called /api/versions/FlightTracker and it will still support default HTTP verbs (so Get() will be hit for a HTTP GET request).

public class FlightTrackerController : ApiController, IVersionApi
{
  private readonly IFlightTrackerVersionRepository _flightTrackerVersionRepository;
  private readonly IConfiguration _configuration;
  public FlightTrackerController()
  {
    _configuration = new Configuration();
    _flightTrackerVersionRepository = new FlightTrackerVersionSqlRepository(_configuration);
  }
  public IEnumerable Get()
  {
    var result = _flightTrackerVersionRepository.Get();
    return result;
  }
}

Here’s the additional WebAPI route which sets up our route. Note the new constraint object where everything gets tied together.

config.Routes.MapHttpRoute(
  name: "Versions",
  routeTemplate: "api/versions/{controller}/{id}/{format}",
  defaults: new { id = RouteParameter.Optional, format = RouteParameter.Optional },
  constraints: new { abc = new TypeConstraint(typeof(IVersionApi)) }
);

The magic happens our TypeConstraint class. It gets a list of all the types which implement IVersionApi, then compares the requested controller (e.g., a request for “/api/versions/FlightTracker” will match “FlightTrackerController”) with each of the types then returns a bool. We implement the MVC IRouteConstraint interface – see Creating a Custom Route Constraint.

public class TypeConstraint : IRouteConstraint
{
  private readonly Type _type;

  public TypeConstraint(Type type)
  {
    _type = type;
  }

  public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
  {
    var controller = values["controller"];

    if (controller == null || string.IsNullOrWhiteSpace(controller as string))
  	  return false;

    var type = _type;
    var types = AppDomain.CurrentDomain.GetAssemblies()
	  .SelectMany(s => s.GetTypes())
	  .Where(type.IsAssignableFrom);

    var matchWith = controller + "Controller";

    if (types.Any(o => o.Name == matchWith))
	  return true;

    return false;
  }
}

Hope you find it useful!

Flow – Workflow template based software

Flow is my experiment into workflow template based software.

Rigid software is a pain to customise

I used to work in a company where their source of revenue was from sales of a single software package. This software package was designed to record customer information and then schedule and manage jobs to service the customers equipment. The package was generic in order to fit as many domains as possible. This confused lots of customers because the items they sold weren’t in the language of the customer. For example, instead of selling or maintaining houses and equipment, they’d have to use products and parts, so would refer to houses as products and equipment as parts.

Every day there would be requests for additional functionality, or a change of its behaviour because it didn’t mirror the way they work closely enough. For example, customers sometimes needed to send an email or calculate a field elsewhere after something had been added to the system. If we added an additional step for one customer, it would affect another customer who wanted the opposite Where do you stop when you start to alter the software for one customer but need it to be generic? That is still a problem for my old company.

Like clothes, we need something simple as a general fit to get started, but then as we mature we can get something tailored which would suit us better and be less wasteful.

How would this work? Lets take this example of adding a new customer. We collect the data from a form and store it in the database.

Flow 1

If this was traditional software, after it’s been shipped, the process can’t be altered because the routines are hard coded. What happens if your biggest customer comes to you now asking you to alter this process because it’s important for them to send an email to the Customer Team every time a new customer is added to the system? Looks like you’ve got to go back and recode the software, then ship it with a set of feature toggles so it sends emails:

Flow 2

Imagine if the software we shipped was a system of workflow templates. If a customer wanted an additional custom action, they could add additional steps wherever they needed to. Customers that just wanted off-the-shelf-software wouldn’t need to do a thing, as they’d never make any changes.

Templated actions or their properties could be locked at the discretion of the template developer leaving everything else would open to customisation. Locking actions is only useful when updating the software versions, so an upgrade would update all the standard actions – the ones that were supported, and wouldn’t remove any custom actions. If actions were removed by the developer, this would cause a few merge issues so that needs thinking about.

Flow

I think I’d quite like to create a workflow template based solution. I’m going to concentrate on something web based to start with, designed to be portable for any platform. I’m going to write it in C#, and probably hosted in Azure to start with. It’s also going to be designed so it can be taken offline and needs a way that it can be updated, tested, and rolled back.

Actions

  • Collecting data
    This would need forms, form templates, and tie in with validation
  • Validating data
    This would be a custom rules engine linked to any step
  • Storing data
    Where do you store data? How do you set this up? NoSQL would be perfect for this. If we were going to store to a relation database, then mappings would have to be maintained.
  • Sending emails (to customer, internally)
    These need lists of emails, HTML templates, etc.
  • Push notifications
    Send info to phones and push enabled devices in real time. That would be neat.
  • Showing information to the user
    If the user is doing something important, or needs to accept a message first, we’d need a way to show it to them.

Right, enough for tonight, back to work in the morning.