Building a Developer Platform for Mobility

Daniel Yehuda
Coord
Published in
6 min readJun 7, 2018

Insights into the Software Development Process at Coord

Building a developer platform is challenging. You have to start with a conviction that there are pain points with solutions too hard or costly for any one developer to solve for themselves, but that enough developers encounter to make it worthwhile to solve once for everyone. Beyond that, you also need to figure out a language to communicate your solutions to these problems. A developer platform is, at its core, a set of APIs which are in some sense a best guess at how to frame these problems and their solutions. In this post I’ll provide insight into some of the processes we use to build APIs — from how we choose the problems to work on to how we design and begin to execute on the APIs that end up in our platform.

Problems Worth Solving

We start with problems that we believe are real. Based on feedback from developers and non-developers alike, we propose an initiative which aims to solve a specific problem eg. Build a Mixed Mode Routing API With Live Bikeshare Availability. We front-load any research about whether the problem is worth solving and only move forward with initiatives that are ready to be worked on by our engineering team. We call these initiatives shovel-ready, which we take to mean that there has been a demonstrated strong interest in a solution by external parties and that at this point it’s a matter of putting engineering resources towards them. In our experience, working on problems that simply seem useful or interesting to us isn’t a winning strategy.

It Starts with a Design

Once we’ve decided to move forward with an initiative, the engineering work (the fun part) starts! We begin with some kind of a design document. Design docs can start out being very short, high level, and product focused, but may develop into a more detailed technical document, complete with an overview of the current best-guess at the engineering plan. I’ll point out that I’m using the word guess here again, as nothing should ever be set in stone — the biggest benefit of writing the doc is often seen by the writer him/herself, as it forces them to do the hard work of framing the problem and iterating on the solution.

A good doc is a living documentthis is a great benefit of working on software (as opposed to hardware) — we don’t ever plan on getting it right the first time! A more product-focused document might be server as a general FYI to everyone in the company, whereas a more technical could be readable only by other engineers on the team. For such documents, I usually start with a very basic template, which helps guide the process. I’ll include the questions I ask myself in filling out each of these sections:

Background

  • Why am I writing this document — what’s the problem I’m trying to solve
  • What information does a reader need to know about the problem before this document will even make sense to them?
  • Why is any previous work that we’ve done not sufficient for solving this?

Objective

  • What is the summary of the solution being presented?
  • What parts of the problem does this solution solve and what parts of it still remain?
  • What are the non-goals here — what other similar problems that someone might accidentally assume will be solved will explicitly NOT be solved?

Design

  • What engineering changes need to happen to implement the solution?
  • What are some alternative designs and why have you opted against them?
  • What are the risks to the design you’ve outlined and why is it okay to go ahead with it anyway?

Building from the API Down

Now we code, right? Well, sort of. Most our solutions involve building some kind of an API, either internal (think microservices) or external (that’s our developer platform!), so the next step in the process is often to design the API. At Coord, this takes the form of an OpenAPI (formerly known as Swagger) YAML spec. We typically write the API before the code that backs it because, like a design document, writing a spec forces us to think about how to frame the problem and its solution, but to an even more detailed level. An OpenAPI spec literally defines and documents the data model, endpoints, and methods of the REST APIs we build. In fact, because they are structured data, we’re able to use them to auto-generate our server boilerplate: everything from our internal requests/responses to the request routing is logic comes auto-generated for free, from the spec. We use an open-source system called go-swagger to do this, since all of our API backends are written in Go. We also auto-generate pretty documentation from the same specs using Apiary.io and could easily use any number of other utilities that speak OpenAPI. Here’s an excerpt from our mixed-mode router’s OpenAPI spec. You’ll notice that the documentation is deeply integrated.

paths:
/route:
x-summary: Find a route
get:
operationId: route_search
summary: Find a route.
description: |
Find possible trips between two points using either or
both of bike-share and transit.
parameters:
- name: origin_latitude
in: query
description: The latitude of the origin point.
type: number
format: float64
required: true
x-example: 38.908751
...
- name: modes
in: query
description: |
The modes we can use in returned trip options. If not
set, we allow the use of any mode. Note that walking
is always permitted.
type: array
collectionFormat: csv
items:
type: string
enum:
- bus
- rail
- metro
- bike
...
responses:
200:
description: Success.
schema:
$ref: '#/definitions/TripCollection'
default:
description: Unexpected error.
schema:
$ref: '#/definitions/Error'
definitions:
Error:
type: object
properties:
code:
type: integer
format: int32
message:
type: string
TripCollection:
type: object
description: All of the possible trips for this journey.
properties:
no_trips_reason:
type: string
description: |
If we can't find any trips for this journey,
`no_trips_reason` will contain a human-readable explanation
of why.
trips:
type: array
items:
$ref: '#/definitions/Trip'

Don’t Forget to Review

Okay, so boilerplate generated and documentation ready. Coding time! There’s one more step which is worth being explicit about and that’s code review! At Coord, we’re pretty serious about having every line of working code looked at by more than one engineer. In the case of API design, we treat the OpenAPI spec file just like any other code and that means that we subject it to the same review process that we would any other — we generate pull requests for every new API spec and by extension, any other changes to it. In fact, because our APIs are our product, getting this part right might even warrant some extra vigilance — the API is, after all, the one part of software that’s a little firmer, in that once it’s out there and being used, changing it too often will burden our users. We use GitHub and tools like Reviewable to make the code reviewing process easy.

All of the above is to say that building a developer platform for mobility requires planning and iteration at every stage.

Hope you enjoyed!

--

--

Daniel Yehuda
Coord
Writer for

A software engineer, residing in New York City and Remsenburg, Long Island. I work for GV.