-1

I've been refactoring some of my procedural code to OOP, and I'm wondering if using the adapter pattern is overkill in this case.
Basically, I created a Order class. All class properties are a field in the database:

class Order {
    private ?int $id = null;
    private float $value;
    private string $date;
    private string $time;
    ...
}

These orders are sent by third party APIs, and each API has it's own JSON format. For example the date property, one of the APIs might give me creation_date as the field name, other might send just date, or datetime, etc.

I have a HTTP endpoint on my end for each third party. Each third party have a panel/dashboard in which I specify the endpoint. Whenever an order comes up on their end, they automatically send it to me through the endpoint I specified!

Initially, I've been thinking about doing something like this inside the Order class:

public static function create_from_thirdparty_one( $api_data ){
    $instance = new Order();
    ...
    return $instance;
}

public static function create_from_thirdparty_two( $api_data ){
    $instance = new Order();
    ...
    return $instance;
}

But as I integrate with more APIs, this seems.. I don't know, awkward?
So, I though about using the Adapter pattern! But since I'm not familiar with desing patterns, as this is my first time working with one, I though about asking you guys, so.. what you guys think? Is this an acceptable use case?
Thank you!

5
  • 1
    It's not clear to me how you receive data from the third parties. Assuming you receive it through some sort of API (e.g. an HTTP endpoint), it is generally the job of the API layer to convert the third party-specific data into agnostic, domain objects. In such case, you would not need the Adapter pattern because you simply create the correct Order objects from the third party specific code. Commented Aug 18, 2021 at 12:52
  • Hi @VincentSavard! Those third parties have a panel, or a dashboard which I have access, in which I manually register my endpoint. So for each third party I have to create an endpoint on my backend, then I go to their dashboard and specify the endpoint URL! Then, whenever an order comes up on their end, they automatically send it to me through the endpoint I inserted on their panel
    – Matheus
    Commented Aug 18, 2021 at 13:02
  • Do you use the same endpoint for every third party, or do you have a unique one for each of them? Commented Aug 18, 2021 at 13:08
  • @VincentSavard Right now it's a unique endpoint for each third party. Two third parties = two different endpoints! But I could have a single endpoint and distinguish each third party with a GET parameter, perhaps
    – Matheus
    Commented Aug 18, 2021 at 13:16
  • If we were speaking about XML, I would immediately suggest XSD to turn one XML into another. The closer to XSD I have found for JSON is JSON Schema. Opis_JSON is made for PHP. Check out mappers to know how could you turn one JSON into another. The thing is to enable a single endpoint in your end and apply different schemas. If mappings must be dynamic, then you might need to define stages. In that case, the pipeline pattern fits perfectly.
    – Laiv
    Commented Aug 18, 2021 at 14:27

1 Answer 1

1

Design patterns typically have a well-defined structure, such as a class hierarchy in the object-oriented world. You discover that you implemented a pattern when the hierarchy you created match the same hierarchy of a known design pattern. With experience, you may begin to identify beforehand that your use case is appropriate for a certain design pattern, but it is generally a mistake to blindly search for a pattern to use for a situation. They are not building blocks that you use to build an application, merely a communication tool when discussing with other developers.

Back to your question. You suggested the addition of third party specific methods to the Order class. You correctly identified the awkwardness of the situation. The more third parties you integrate with, the more methods you will need to add. The Order class would be coupled to every single third party you may integrate with. This violates the open-closed principle.

Instead, you want to isolate the third party-specific logic from your domain and from the other third parties. If the API of one party changes, it should not affect the implementation of the other parties, as they are unrelated.

Since you already have a distinct endpoint for each third party, you have the perfect integration point to convert their specific payload to your agnostic Order object. Instead of adding a method to the Order class, leave the implementation responsible to parse and convert the payload in the implementation of the third party's endpoint. This allows the decoupling of every third party from one another and from your model, while ensuring that each implementation is cohesive.

1
  • I think you're right; perhaps the solution is simpler than I thought. Thank you, friend :)
    – Matheus
    Commented Aug 18, 2021 at 18:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.