Allowing access to a remote, third-party API through own server's endpoint

I was looking to join a path to a remote, third-party API; the end goal being to authorise user requests to this external API, based on their role in our own system.

The remote API has their own model which I’d prefer to avoid mapping in depth. Users are currently able to use their own access tokens for the service however this limits some functionality in places where it would be acceptable for them to have access.

Essentially, my current mental map of a simple request flow is:

  1. Receive request from client, targeted at our designated path/endpoint. (e.g. /api/external )
  2. Role-based auth. by target and method. If authorised then…
  3. Copy their request, prefixing the client’s target with the remote API’s location. (e.g. ' . $request->getURI() ).
  4. Attach an authorisation header and token, for the remote API.
  5. Send request to remote API.
  6. Receive response.
  7. Return that response to the client.

I’ve little idea of what a decent approach for this is, as I’m very fresh to this space (and am actively exploring it.)

I’ve been trawling through the documents, looking for some examples of similar implementations. ~I have to say, there’s an incredible amount of resources available (and product offerings), which is just fantastic.

I wasn’t able to find anything specific, which does leave me wondering if my overall plan is outside good practice.

Being new to all this, I’m still familiarising myself with general terminology and structure so I think it’s quite likely I’ve missed some useful documentation along the way.

Project Details

I’m just working off the mezzio-skeleton, though I’m thinking I’ll need some implementation of an HTTP client as well - for making requests of the remote API.

If there’s a cleaner, or well-suited approach to this, I’d greatly appreciate any suggestions and/or pointers.

My current half-implementation is through pipelining the call to a Middleware, e.g. $app->pipe('/api/external', ExternalAPIMiddleware::class), which would handle:

  1. Authentication & authorisation on our end.
    (looking at laminas-permissions-rbac, though I’ll keep it simple for the initial design.)
  2. Authentication token decoration, for remote API.
  3. Fetch the request from remote.
  4. Pass the returned response back to our user.

I’m sure I could also split this into multiple steps, once I have an initial implementation working.

Sorry for the long write-up here, and please let me know if there’s further details I can provide to help clarify.

Hello and welcome to the forums :wave:t2::blush:

From what I can see, you have already a really good outline of the steps it takes. Do you have any specific questions? Just ask. I’m giving some feedback to the illustrated scenario that will hopefully get you started.

To separate these layers, you can add more Middleware instances to a pipe. In your case, you can add in a AuthenticationMiddleware before the ExternalAPIMiddleware, which will verify access is only granted to authorized authenticated users otherwise ExternalAPIMiddleware is not being called.

$app->pipe('/api/action', [

You can read more about Authentication in the mezzio-authentication documentation. There is also a component for Authorization mezzio-authorization.

To consume the external API, there a plenty of packages. It mainly depends on what kind of an API (REST, RPC, SOAP, …) it is.

Hope that helps you getting started. Let me know, if you have further questions.