Universal structure or service for API to API Conversion - php

As part of an App i'm developing there's a requirement to create a conversion between our RESTful JSON API and a number of other formats. The intention is to allow output from our API to be converted to make further requests to API's that use different formats such as SOAP, or other REST based API's with different requirements.
A few examples of the kind of things I think this might need to do:
manipulate the JSON output to use different keys (and maybe only a subset of
data
convert to an XML packet/document
convert to a valid SOAP request
output data as a specific filetype/structure (such as csv)
I'm interested really in what approaches should I be looking at here. It would seem to me that this should be a fairly common request so i'm interested if there are specific libraries I should look at, or existing services perhaps. If such a service doesn't exist then ideally I want to create a common structure whereby the 2 disparate services can be mapped using a universal set of tools that are just then configured to work together. This will be within a Laravel PHP application so any Composer compatible library would work.

Following on from my comment:
"I am not aware of any such library to do this, but as a rough guide I think you probably want to create some kind of adapters which all use a common interface. These adapters can then be written to deal with the conversion you are trying to achieve via some open-source library. Manipulating the output might be a good excuse to use the decorator pattern :) Sorry I could not be of much more help."
An example of what I think you are after is the following:
An interface for your adapters
interface DataConvertor
{
public function convert(DataInterface $data);
}
An interface for the data you are passing around (the data will be an object also with a common interface to work from).
interface DataInterface
{
/**
* returns a json string
*/
public function asJson();
}
Then you can create your adapter for use with some 3rd party library.
class SomeThirdPartyNameAdapter implements DataConvertor
{
public function convert($data)
{
//some logic here to make my data object with a known asJon method
//suitable for use for some 3rd party library, and use that library.
$rawJson = $data->asJson();
//manipulate this as needed ($compatibleData)
$thirdPartyLib = new ThirdPartyLib();
return $thirdPartyLib->thirdPartyMethod($compatibleData);
}
}
Obviously this is just a rough guide and there may be other parts of this you can make abstract (e.g. have the adapters implement the DataConvertor interface but also extend some abstract class to inherit some functionality, or other method to add to your interface).
Hope this helps

Carl is right that a great approach is to create some adapters using a common interface. Then you can provide implementations that convert JSON to XML or JSON to a CSV, etc.
However I would strongly recommend looking into Mule ESB as a solution as well. http://www.mulesoft.org/
It's a Java based, open source project that allows you to do pretty quick and efficient integrations. For example, you could create a "flow" (a Mule term) that makes a RESTful call and then converts the data and pumps it out to a specific destination (CSV, SOAP call, XML, etc.)
The real selling points of Mule (things that have worked great for me):
Very easy to deploy. It works similar to something like Tomcat, where you can deploy a package and it runs on a server.
Tons and tons and tons of boilerplate code already done for you.
Free and stable. They have tons of high profile customers so it's pretty battle tested and we've been able to get their free version working in production with no trouble.

Related

Using Amazon MWS (Inventory API) with CodeIgniter (PHP)

I'm somewhat familiar with using the Amazon MWS apis, but I'm new to CodeIgniter and the whole hmvc thing. I'm curious how I would add the api into CodeIgniter. Would I have to dissect the entire api into the appropriate mvc folders, or could I just add it as a library. If the latter is the case, how would I use the api?
I'm sorry if this is vague, but I would greatly appreciate any help you're willing to offer! Thanks
I cannot say anthing specific to CodeIgniter, but I've worked with various MVC libraries, so I can give a general overview. Your options are:
I) Write a model from scratch
New code accessing the MWS would mostly end up in the "Model" space. The controllers and views (which you'll probably eventually need) are outside the scope of the code that Amazon provides, so they need to be written anyways. As far as the MVC (and OOP) idea goes, this is the "proper" way to do it, you can make full use of inheritance and polymorphism.
Advantages: Your model accessing the MWS will follow the rules and guidelines of your MVC framework. It will be easy to integrate into other parts of the framework, and integrate nicely with the rest of the code.
Disadvantages: lots of code to write and (more importantly, since MWS is a moving target) maintain.
II) Use Amazon's code as a library
Amazon's code would go into the "Libraries" space. As it doesn't follow the rules of your MVC framework, it will "feel" foreign to the rest of the code.
Advantages: Less code to write and maintain.
Disadvantages: No usage of the framework, no code reuse, no inheritance and no polymorphism.
III) Write a wrapper
This is basically a mix of the two options above. You write a very thin wrapper around the library (goes into the Model space) which calls the unmodified Amazon library. Written properly, you might get a "best of both worlds" - this depends on how much the interface the library matches your desired model interface.
Advantages: Often only little extra code is needed, when compared to the "library" approach", while the model can be used in the same way as a complete rewrite.
Disadvantages: Sometimes needs almost as much code as writing from scratch.
Suggestions and Comments
My approach would probably be to go with a wrapper, unless I need just a fraction of the library's code. Since PHP does not have a strict object hierarchy, it is usually possibly to properly mimic inheritance anyways if needed.
A side note on designing a model around the MWS: Unlike most web services, some calls to the MWS API (e.g. SubmitFeed) work asynchronously in that information about the success or failure of an operation will only be available minutes (or even hours) after the call has been made. Most MVC model hierarchies and interfaces are not designed to handle that type of thing well, so a complete rewrite might not give you the benefits that you'd normally get.
Please remember, that I have no knowledge about CodeIgniter. Your mileage may vary.
My solution is specifically for the Yii PHP Framework but principle should work modifed for Codeigniter external library autoloader:
Put the entire Amazon MWS PHP SDK into your Vendors folder or into an Extensions folder or whatever CI prefers for external libraries. You might have to create that folder and refer to it within CI
Then find out how to use CI's autoloader so it autoloads the library from step 1 above.
Then just call whatever part of the Amazon MWS library from step 1 from your controllers.
This is quick reply, so if I've missed something let me know so I can edit.
For more in-depth discussion visit below to see how we overcame this along with exact code we used for the autoloader and other things dealing with the Amazon MWS PHP SDK
http://www.jescor.com/amazon-price-update-program/

Api/plugins for open source libraries?

whenever i use a open source library eg. Doctrine i always ending up coding a class (so called Facade) to use the Doctrine library.
so next time i want to create a user i just type:
$fields = array('name' => 'peter', 'email' => 'peter#gmail.com');
Doctrine_Facade::create_entity($entity, $fields);
then it creates an entity with the provided information.
so i guess, all coders will create their own "Facade".
i wonder how usual it is with open source Facades to download and interact with the open source libraries? is this rare cause i haven't seen any of these. in some frameworks i have seen them called plugins, eg. plugins for twitter api or facebook api.
so whenever you download a library, should you search for plugins/facades on the net, or is it better to just try coding your own? i just thought it would be great for everyone not to reinvent the wheel.
thanks.
Let us say it is not just about Factories, let us say, you really often write Facades for libraries you use. What is the point? Why are you doing it? The point is, that you use the library in a specific way. If the Facade you write was universal and everybody tended to write something like that, the Facade would be surely part of the library. So the reason why it is not and why you want to write it is, that you use it in a very specific way, which is specific to you application of the library. So you transition from the abstraction of the library to the abstraction of your application. This can remove much of the complexity of the library from your application, but it also restricts the way in which you use the library. So, if you understood my point, you might be convinced, that there is no point in releasing each Facade for certain way in which the library can be used. However, sometimes, when we talk about a big influential library, which is combined with some other libraries and together comprise abstraction, which can be widely used, it may happend that new library will be created.
The aim of a Facade is to (quoting)
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
Wrap a complicated subsystem with a simpler interface.
While the above can be said to apply to your example, it feels much more like an AbstractFactory to me. You might want to rename it to EntityFactory without the Doctrine part, because the fact that it uses Doctrine internally is an implementation detail. For the public facing API of the Factory, it doesn't matter. Maybe you want to change from Doctrine to Propel at a later time and then you just have to change the code inside the class, but not the API.
You might also be interested in the Gateway pattern.
But to answer your question whether this is a common approach: yes, I think so. Abstraction makes code easier to understand and easier to maintain. But since the API of the facade/gateway - whatever applies - is usually determined by what the application does, it rarely can be reused, so I doubt you will find readymade facades/gateways on the web.

Best practices for an API in PHP : functions, or classes?

In my company we have developped some applications. We have to create an API for one application (say application A), so that the others can use it (an its data).
The question is : we already have developped PHP classes for the model of Application A, if we want to create an API, should we :
- re-use these classes (too much functionnalities for an API, too heavy...)
- create one PHP class, with some basic functions, that takes in input and returns only raw values (like strings, array... NOT complex classes)
- create another set of PHP classes, simpler, and designed only to be used by an external application (so only to get data easily)
Usually, an API is the 2nd solution (to be used as well with PHP than as a web service for example), but i find it too bad that we made a complex and usefull class modelisation, then we tear it apart just to have functions, strings and array.
The 3rd one seems to me to be the compromise, but a collegue of mine insist that this is not an API. Too bad...
What do you think ?
Solution number 3 might be the best one from an architectural point of view. Basically you are using a Facade Design Pattern to simplify your API. Since I am dealing with it at the moment: In Patterns Of Enterprise Application Architecture this approach is described as the service layer which makes totally sense since you don't want to expose any user (meaning whoever will deal with your API) to more complexity than is actually needed or desired.
This includes using the easiest possible interface and transfer objects (raw values if they make sense). As soon as your Facade is being called through remoting services (like a webservice) you will eventually have to break repsonses and requests down to raw values (data containers) anyway.
Build a set of Facade classes that simplify the public API.
Create some thin wrappers that implement simpler API over the original classes. DO NOT reimplement any business logic in the wrapper - that'd lead you into trouble if any of the logic changes, as you will surely lose track of which piece was modified and which was not. Keep the external inputs/outputs simple, if you need something more complex than string, use XML or JSON for structured data, but try to avoid too much complexity - if you have 2 things to pass two query parameters might be much better than one structure with 2 fields.
That's the 'Facade' pattern.
I would also say have a look at the Facade pattern.
Build a set of Facade classes that only offers the functionality that is really needed to be public. Those classes then for sure use your current core classes.
This gives you also the advantage that if you change the core classes, the API must not necessarily being changed.

Automatic documentation from PHP code

OK I know there's PhpDocumentor for generating documentation from php code. It seems it hasnt been updated in a long time (but maybe they figure its mostly feature complete).
While this might be good for documenting things for other programmers, it doesn't seem well suited for documenting the external "API" of a web service. IE, if I've got a nice MVC structured project, PhpDocumentor might be great for documenting all the models and internal libraries and such for other developers on that project, but how do I document the web service it provides?
I am thinking something where you could document the methods on the controllers using tags like:
/**
#service /device/add
#access POST
#return JSON
*/
which in the generated docs would show that you need to do a POST request, it returns JSON data and the URL to access it is http://whatever.com/device/add. Obviously there would be a global config file for the documentation that defines what the base url is for these service calls.
At this point I am thinking I will just implement something myself using reflection on the phpdoc blocks (or using Annotations with the addendum library) and have the docs accessible dynamically right in the application.
You might prefer DoxyGen (or PHPxRef) to PhpDocumentor .
"While this might be good for documenting things for other programmers, it doesn't seem well suited for documenting the external "API" of a web service".
Why not put DoxyGen (or whatever) comments only into the API functions which are externally visible?
Give a description of each and use #param [in], #param [out] and #return.
Wouldn't that achieve what you want? Or did I miss something?
I think what your asking (documenting an API (especially if its RESTful)) would be to use a WADL. Granted its not going to be generated from source (no tools for that in PHP), but a WADL is excellent for documenting a service.
You can have sample payloads in all sorts of media types, all the response codes and how you handle them -- really everything you need.

Generating objects in PHP using REST

I am trying to make a decision whether I should use a REST service or a SOAP service for some web facing functions that I am producing. This decision is based on whether I can easily use the REST service in implementation. I would prefer to use REST, though I don't want to spend days coding the object model in PHP.
The services are being developed in .NET but will be consumed mainly by PHP.
Basically it has come down to one point: Ease of integration. Using SOAP in PHP I can use the NuSOAP library, which will generate the object model.
However with REST I cannot seem to find a way to easily generate that model, if this is possible I would use REST services as they are easier to document and extend, and also have the JSON abilities as well.
Can I generate an object model in PHP from an XML file/schema that I could then serialize with the REST service?
You might not even have to go the class route. Simply ingest the data using simplexml and then traverse it as if it were an object. Or if you have json, json_decode($data, TRUE) would do the same thing (without attributes in brackets).
$ch = curl_init("http://example.com/some/rest/endpoint");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$data = curl_exec($ch);
$obj = simplexml_load_string($data);
print $obj->some->data->you['need'];
That would print here if your XML was something like
<_>
<some>
<data>
<you need="here" />
</data>
</some>
</_>
I had some trouble getting SOAP to work between diffent languages (PHP <> JAVA and PHP <> .NET)
If your going with SOAP, you might want to check out WS-I (Web Services Interoperability)
Based on your described requirements you should stick in the SOAP world. Remember, REST is just a style of architecting a distributed interface. It says nothing about how the functionality of that interface is implemented. There certainly is no need for mapping schemas to objects.
Having said that, if you look at the client tools in the WCF REST Starter kit you will find functionality to paste XML as a CLR type. This will do a best guess at creating a serializable class based on an XML instance document.
Also, from what you are describing ADO.NET Data Services would provide you a quick way of exposing RESTful data services to your PHP site.
....
Here is a question for you? If the .Net services are going to be consumed by a PHP site then why would you describe the .Net services as "web facing". From your description, these services sound more like a private implementation detail of your web site.
If I were you I would:
investigate if NuSOAP tools can be used on just XSD. In the .NET world, you have svcutil (or in the ASMX days, wsdl.exe) to digest .wsdl files to produce proxy classes. But if you have only .xsd files, you can use the xsd.exe tool, or the "aftermarket" XsdObjectGen, which is like a supercharged xsd.exe. Are there similar tools in NuSOAP to do the same? Maybe this is obvious and you've already done it.
if that doesn't pan out, produce a dummy WSDL, and stuff the XSD you have into it. Then, process the .wsdl file with the NuSOAP tools. Grab the generated code, and remove the soap envelope and communications stuff, but retain the object serialization stuff. Not sure if this is possible, the way the PHP (or is it C?) code is generated by the NuSOAP tools. In .NET, it's easy to break the different pieces out.
The whole idea behind rest is that you do not use it with hackish "object models" like with SOAP. The problem is you're trying to use the system wrong :)
If you want object models, use SOAP.
If you want web-friendly APIs, use REST.
For ease of integration, I'd go with a REST API. Since there is such a strong convention, integrating should be relatively straightforward for anybody's who's worked with REST before.
So i think this could be something that i am looking for. but i would like to know if there is some sort of automation system out there for it
found it at http://devzone.zend.com/article/1713#Heading11
Extending Classes
While the above examples were all
doable with PHP 4 and the domxml
extension (only the API was a little
bit different), the ability to extend
DOM classes with your own code is a
new feature of PHP 5. This makes it
possible to write more readable code.
Here's the whole example again,
re-written to use the DomDocument
class:
class Articles extends DomDocument {
function __construct() {
//has to be called!
parent::__construct();
}
function addArticle($title) {
$item = $this->createElement("item");
$titlespace = $this->createElement("title");
$titletext = $this->createTextNode($title);
$titlespace->appendChild($titletext);
$item->appendChild($titlespace);
$this->documentElement->appendChild($item);
} } $dom = new Articles(); $dom->load("articles.xml");
$dom->addArticle("XML in PHP5"); print
$dom->save("newfile.xml");

Categories