omposition<\/em> design principle here.<\/p>\n <\/p>\n
By coding to interface we can choose different implementations of the transport and even swap them at run time. Personally I also use couple helper classes to pass data in and out of the transport: Request<\/b> and Response<\/b>.<\/p>\n
Now we can use the interface to test our code without hitting an actual API endpoint. We just need to create a fake transport class that implements Transport<\/strong><\/em> interface and returns a dummy data. We can pass this class to ShopifyApi<\/b> when running our tests. In this refactor we use Dependency Inversion<\/em> design principle<\/p>\nNow let’s split up our ShopifyApi<\/b> “super class”. We can take each responsibility this class handles and split them out into their own classes<\/p>\n
<\/p>\n
This refactor takes advantage of OOP’s\u00a0Inheritance.<\/em>\u00a0 Depending on responsibilities, parent class can be either abstract or concrete. Child classes can be as small as containing only one method. Don’t make this fact keep you from refactoring: “Well, if we extract Fulfillment<\/b> class, it will only have one method, so it is wasteful allocating the whole class to it”. It may be true now, but later on Shopify will change the way they want you to send fulfillments. For example recently Shopify added locations. Now your Fulfillment<\/b> class has to figure out what location to use when sending a fulfillment. The good thing about it is that you only have to change Fulfillment<\/b> class. Your client code still uses the same interface and does not know about the changes. You can see how Single Responsibility<\/em>\u00a0and\u00a0Encapsulation<\/em> pay off in this case.<\/p>\nIn multi tenant applications you may have to use different API credentials for different clients.\u00a0 In this case you can create a some kind of credentials provider.\u00a0 So your design may start looking more like this:<\/p>\n
<\/p>\n
Before you start implementing credentials provider, first think if you really need it. Personally I am against unnecessary complexity and use YAGNI.\u00a0 “You aren’t gonna need it”\u00a0<\/em>is a principle that states functionality should not be added until necessary.\u00a0 If your app does not support multi tenancy chances are it won’t do it in the future.\u00a0 Multi tenancy requires a different design approach.\u00a0 If your app uses only one set of credentials to connect to Shopify API, keep it simple and don’t develop unnecessary\u00a0structure to provide credentials to the API client.\u00a0YAGNI.<\/p>\nAs you can see, the design can become quite involved.\u00a0 I suggest using common sense when creating an API client.\u00a0 If your app only needs to sync products from Shopify, the suggested design complexity may not be justified.\u00a0 But if there is a lot of stuff going on and your app uses a lot of endpoints, it makes more sense to have a testable design that can accommodate future changes without requiring much work.\u00a0 The more time you invest in building a software, the longer you expect it to live.\u00a0 This means you should be able to easily adapt it to changing requirements and make necessary updates fast.<\/p>\n","protected":false},"excerpt":{"rendered":"
When you extensively work with certain APIs, like Shopify’s for example, you will end up with bunch of functions that map to API’s endpoints. One of the approaches I have seen so far is to create an API class ShopifyApi and make those functions class methods. So it looks something like the figure below. I…<\/p>\n","protected":false},"author":1,"featured_media":791,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[10],"tags":[],"class_list":["post-784","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php-mysql-development"],"yoast_head":"\n
API Client Design | Alex Rusin Blog<\/title>\n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n \n \n \n\t \n\t \n\t \n