DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • From Naked Objects to Naked Functions
  • Fine-Tuning Performance, Resolving Common Issues in FinTech Application With MySQL
  • Schema Change Management Tools: A Practical Overview
  • How to Build a Full-Stack App With Next.js, Prisma, Postgres, and Fastify

Trending

  • Part 1: Building Governed MCP Tool Services With Quarkus LangChain4j and Goose
  • Why Spark Executors Leave Cores Idle on YARN: A Packing Model for Executor Sizing
  • Fix the Target, Precompute Once: A Backend-Free Word-Ladder Solver With a BFS Distance Field
  • Treat Salesforce Configuration Like Code: Release Discipline in a Copado Pipeline

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Data Engineering
  3. Databases
  4. Practical PHP Patterns: Gateway

Practical PHP Patterns: Gateway

By 
Giorgio Sironi
·
Sep. 09, 10 · Interview
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
11.5K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

A fundamental trait of modern software is that it does not live in isolation, especially in the realm of web applications, which can easily interact with external resources like web services and databases.

The majority of PHP applications must access external resources, that by architecture do not run in the same memory segment or programming language of their core Domain Model. There are many examples of these situations:

  • web services like Google's or Yahoo! ones.
  • Relational and NoSQL databases.
  • The filesystem of the server.
  • Other web and non-web applications for data interoperability.

I'll call any instance of this external dependency a resource, which is an umbrella term for each item of this list.

Motivation

When you have to access an external resource, you get an API which you code may call. However accessing an API directly, like a PDO object or a HTTP request stream, presents many issues.

First of all, your application ends up becoming very coupled to the particular product or application instance you're using. There is no room for change, since every resource has its specific API, unless it is a commodity like a relational database.

More subtly, general purpose APIs are designed as catch-all interfaces for providing any functionality, and capturing any use case from every possible client. The entire set of methods becomes a possible requirement of your application, since you cannot instantly easily distinguish the primitives really called by your application from the one ignored.

Moreover, the external resource may use data formats and models different from the ones used by your application. This is the case with relational database used as a storage for object models.

Implementation

There is an easy solution to these interaction problems, which I feel is never pushed enough. The Gateway pattern is this solution: wrap into a single object all the interaction specifical to the integrated resource, so that your object provides a specialized API of exactly what you want, as you want.

This pattern is similar to the Facade classic one, but it is applied on other people's code instead of our own. You can also compare it to an Adapter, when the Adaptee is not even object-oriented or in the same process of your application's code.

By the way, this pattern is specialized by many other ones, and it can be thought of as their superclass.

Wrapping

Wrapping is the mechanism used for this pattern's implementation. Only the functionality needed is really exposed from the Gateway.

This minimalism help the Gateway in becoming the target of integration tests or pragmatic unit tests that exercise only the functionalities actually exposed and that may cause a regression. This pattern insulate the application layer or the Domain Model from external changes.

The Hexagonal Architecture is really an evolution of this pattern applied systematically to every external resource, until only an in-memory object structure stands as the core domain, and every dependency is injected as an adapter for an application's port.

A Gateway can also be implemented with more than one object (back end and front end) when the work to do is both on the protocol side (procedural vs. oo, XML vs. variables) and at the workflow side (different slicing of functionalities, APIs at the wrong level of abstraction fro your use case).

Advantages

I'll never get done with talking of the advantage of introducing a Gateway over an external dependency.

You achieve greater insulation over the dependency: changes do not spread into your system and you can test them separately and efficiently.

The system is also easier to read and understand as it does not pull in the whole complexity of the resource, but only the abstraction needed by client code.

Disadvantages

There's hardly any downside in coding up a Gateway class, unless you introduce a leaky abstraction.

Peculiarity

According to Fowler, this pattern is somewhat different from the other integration-related ones, and due to these differences it has earned a name and an article here.

  • A Facade simplifies a complex API, and it is written by the developers of the resource used. A Gateway is written by the client code developers to simplify their own job. The Facade also implies a different interface, while Gateway can simply wrap it and transform it or hiding part of it.
  • An Adapter alters an implementation to provide a new API. With a Gateway there may not be an existing interface, or if there is, the Adapter is part of the Gateway implementation, which comprehends a back end side.
  • A Mediator separates different objects, but Gateway is much more specialized in separating two objects and keeping the dependency side (the external resource) not aware of being used.

Example

Today's example is a Gateway to a web service, in the form of the classic Twitter client. For simplicity and readability we'll deal only with a single operations that does not require authentication, badly implemented with OAuth by Twitter at the time of this writing.

<?php
class TwitterGateway
{
/**
* the only functionality I need from the feed
*/
public function getLastTweet($username)
{
$endPoint = "http://twitter.com/statuses/user_timeline/{$username}.xml?count=1";
$buffer = file_get_contents($endPoint);
$xml = new SimpleXMLElement($buffer);
return $xml->status->text;
}
}

// having an object to represent Twitter means we can mock it,
// pass it around, injecting it, composing it...
$gateway = new TwitterGateway();
// client code
echo $gateway->getLastTweet('giorgiosironi'), "\n";
PHP application Database Relational database unit test Object (computer science)

Opinions expressed by DZone contributors are their own.

Related

  • From Naked Objects to Naked Functions
  • Fine-Tuning Performance, Resolving Common Issues in FinTech Application With MySQL
  • Schema Change Management Tools: A Practical Overview
  • How to Build a Full-Stack App With Next.js, Prisma, Postgres, and Fastify

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook