Category Archives: EasyJet

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!

Data Generation Plans with Windows Azure SQL

Visual Studio cannot create Data Generation Plans for Windows Azure because the schemas aren’t compatible.

These are the steps you need to take if you want to generate data for an Azure database.

  1. Import your Azure database to your local SQL / SQL Express instance on your development machine
  2. Create the data generation plan using the local database
    data generation complete
  3. Use the SQL Database Migration Wizard to create your migration backups
    SQL Migration Wizard - Script Wizard
  4. Continue with the SQL Database Migration Wizard to publish to a database in Azure
    Target Server Response

Useful links

Asynchronous C# Programming

A few useful links from an email I was sent from one of our Enterprise Architects (Ali Kheyrollah). I thought I’d best put it here before I delete it!

Don’t use void as a return type
http://blog.filipekberg.se/2012/09/20/avoid-shooting-yourself-in-the-foot-with-tasks-and-async

Example MVC page with example deadlock gotchas
http://www.tugberkugurlu.com/archive/asynchronousnet-client-libraries-for-your-http-api-and-awareness-of-async-await-s-bad-effects

Other lessons learnt (ByteRot) (Ali Kheyrollah)
http://byterot.blogspot.co.uk/2012/08/tpl-async-parallel-task-library-server-lesson-hard-way.html

MSDN – MVP Summit presentation on async
http://blogs.msdn.com/b/pfxteam/archive/2013/02/20/mvp-summit-presentation-on-async.aspx

Analysing HTTP Request and HTTP Responses

Status Code Categories

Range Category
100-199 Informational
200-299 Successful
300-399 Redirection
400-499 Client Error
500-599 Server Error

Common HTTP Status Codes

Code Reason Description
200 OK Success
301 Moved Permanently Resource has moved, don’t check here again
302 Moved Temporarily Resource has moved, but might be here later, so check again later
304 Not Modified Resource was the same as last time (think eTags)
400 Bad Request Probably bad syntax or malformed packet sent from the client
401 Unauthorised Client may need to authenticate
403 Forbidden Server refused access to that resource
404 Not Found
500 Internal server error An error occurred on the server
503 Service unavailable Server will not or cannot service the request

There is generally a three package TCP handshake before HTTP packages are sent.
http://www.inetdaemon.com/tutorials/internet/tcp/3-way_handshake.shtml

A server can only support a certain number of concurrent connections. By default sockets are kept open (persistent connections) and slowly ramp up.
http://en.wikipedia.org/wiki/Slow-start

HTTP 1.1 defines persistent connections as default. If you want to close the connection, you must include the header:

Connection: Close

Tools

Windows Network Monitor 3.4
http://www.microsoft.com/en-us/download/details.aspx?id=4865

Wireshark
http://www.wireshark.org/download.html

Fiddler2
http://fiddler2.com/

Cache Control Directives

Directive Meaning
public A response for everyone
private A response for a single client
no-cache Don’t cache the response
no-store Do not act on this response