afterapi

AfterAPI Released to Keep Old API Clients Working

Aftermarket 0.2.0 adds a second tool. AfterAPI, run as aftermarket adapt, keeps an old client working after the API it was written for has been replaced.

AfterPatch fixes one thing at a time: a renamed field, a missing header, a moved path. That works until the whole API changes shape. Then you’d need a dozen small rules, and nobody could read them as a whole. AfterAPI takes the other approach. You write down what each old endpoint looked like, in terms of the new one, and adapt does the translating both ways.

One mapping per old endpoint

Say the customer API moved from v1 to v2. Lookups moved from a query parameter into the path, the customer is now nested under "customer", and errors arrive as {"error": {"code": ..., "message": ...}} where v1 sent {"message": ...}. The mapping for a lookup reads like this:

- id: get-customer
  old: GET /api/v1/customer?id={id}
  new: GET /api/v2/customers/{id}
  response:
    body:
      customer_id: $.customer.id
      name: $.customer.full_name
      email: $.customer.email
    error:
      message: $.error.message

{id} is captured from the old URL and put in the new one. In a template, $.customer.id reads a value from the new response. Anything the template doesn’t name is left out, so the old client gets exactly the fields it expects and nothing more.

What it can do

  • Move endpoints. Path and query parameters go into the new URL, and the method can change. Query parameters the mapping doesn’t use are passed on as the client wrote them.
  • Rebuild bodies. A request template builds the new request body from the old one. A response template rebuilds the old shape from the new one. $each and $item turn one list into another, so a v2 {"data": [...]} can become a plain v1 list.
  • Map status codes and errors. A 201 can become the 200 the old client expects, and a 204 can become a 200 with {"deleted": true}.
  • Rename headers. Credentials such as Authorization and Cookie are never renamed, set or removed.

All or nothing

A mapping is applied fully or not at all. If a request can’t be translated safely, it goes on exactly as the client sent it. If a response can’t be rebuilt, because the body isn’t valid JSON, is too big, or lacks the fields the template needs at the top, it comes back exactly as the upstream sent it, status and headers included. Every such case is logged as skipped, with the reason. Nothing is ever half translated.

AfterAPI keeps everything AfterPatch has: a dry run that changes zero bytes, an audit log with no values in it (it logs /api/v1/customer patterns, never the IDs), adapt check to validate a file and point out endpoints that overlap, and adapt test to run saved requests through a mapping in CI.

Two fixes in AfterPatch

The review before this release found two problems that AfterPatch shared, and both are fixed there too. A dry run no longer turns a slow response body into a 504. And a client that stalls while sending a body a rule needs now gets a 408 after upstream_timeout, where before it could hold a connection open.

Try it

The quick start now has a second part that runs the old client’s test suite against the new service, first directly and then through adapt. The full mapping format is in the AfterAPI reference, and the binaries are on the download page. How it was tested explains what the tests check and what the review found.