I am busy on a project that involves calling the API's of nine other sites. This number is expected to increase in the future and the actual method of API will differ (SOAP or XML).
There is a specification that each site needs to be modular so that my client will be able to sell them our API (which they can then give to other aggregators).
I've completed a number of Cake projects in the past but all of those were database driven. Can somebody advise what the best way to approach this would be?
At the moment I am thinking of making each API a plugin. I will place the API calls into a model (not attached to a database table) and then the rest will follow naturally. Because the actual views of each API will differ I won't be able to use a common controller or views (each company API we consume has different business rules).
Can anybody tell me if this approach sounds reasonable or if I'm off track?
Thanks,
Andy
Maybe in your root application you could extend AppModel. A SoapModel for Soap-based API calls and RestModel for REST-based calls, etc.
Then in each plug-in, you could make the model extend the appropriate class for the basic communication, and then you only have to handle the site-specific business rules in those models. This extra layer of abstraction would nicely hide away the WS implementation details.
You don't even necessarily need to split these into plugins if you're going the fat model route. Plugins are only particularly useful if you want to self-contain a "sub-application" of some kind and make it re-usable across other Cake applications.
Related
I'm planning a small web application project which will consist of both a website (using PHP) and in the future a mobile application. I want to implement a RESTful API (using PHP) to communicate with the mobile app. But since the API and the website will both be written in PHP and hosted on the same server, it seems a bit odd to make HTTP calls from the website to the public API (or isn't it)?
Anyway, I am considering putting a layer between the API and the business logic, basically just consisting of an object that exposes the same API as the public RESTful API, but as a PHP object that can be accessed directly from the website.
Is this a good or bad idea? Why?
Is this a well known pattern? If so, what is it called?
I found some sites proposing a similar structure and calling it "API Gateway Object", but I'm not sure if that is an actual well-known pattern or just something they came up with tho.
Here's a sketch of what I have in mind:
Good question (answer) ... not sure it is the right kind for this site. I use exactly that pattern, which I ended up rolling out after hard-fought battles with other architectural approaches/frameworks i.e. I dont know its name.
some pros :
Turns out it is also extremely useful for testing, climbing up the abstraction ladder can be easily structured and exercised with your favorite testing toys.
Your mobile data architecture can be a straight isomorph of the Gateway Object model.
It nicely decouples for straight php access AND it still permits you to keep some things in play when it matters : auth, logging, traceability of database access.
It future proofs your design : although it may seem silly at the moment, you may find that you will eventually need to have www and mobile presentations served from different instances. Migrating your php presentation to use RESTful API will be a cinch if you do this right.
An example : Say I have a Message object, this object will have a number of 'normal' classes:
Message : the plain-old-php-object, no side effects, no persistence
MessageDAO : the persistence manager for Message. basic CRUD, no business logic, just elementary CRUD
MessageWF : the workflows offered by the business logic
IBMessageSpec : a specification for a message
OBMessage : the representation of the message that I wish to send to the caller
I use a DI container to inject in each of the above the specifics of the context.
In my Mobile , I have OBMessageSpec wihch is essentially an IBMessageSpec, and IBMessage which maps the servers's OBMessage. That code is pretty much re-useable to multiple instance types, and apps.
It is OK idea. You could provide an API for internal PHP usage via some API Gateway Object and expose RESTful API, that uses same API Gateway Object. It may be named Adapter, because it adapts your php API to be used by external services via HTTP.
But why do you need something to be known pattern to use it ? It perfectly lays on your needs, this architecture allows you to keep your modules consistent and avoid duplications of logic.
You can use RESTful on PHP side, it would be slower, but more flexible - maybe in future you'll need to rewrite backend with some other language - you don't need to change frontend!
So, it is up to you to decide, what is more preferable for you, it is not about patterns.
I am building a web application which has 3 rd party api integrations which include
Payment gateways
Sms vendors
Email providers like mandrill
Now I can have concrete repository classes where functions which talk to my DB resides. As far as I know the repositories are on standard practice used to talk to databases. Now where do I build the logic of calling a 3rd party API resides? Is that what a service provider is meant for? If then can some one show me very basic example of how the whole flow works? For eg sending an sms from a controller by calling the service provider. The question might seems dump but I am not able to get any examples or flow searching it online. There is no real world examples to be seen.
Please give some reference or example if someone has done the same.
TIA!
Repositories are, in the strict sense, for encapsulating methods for advanced access to a set of data.
That being said, there is nothing that says this is the only way to use them. The pattern itself allows for you to group different processes into different places, improving the organization of your code.
At this point one could argue they are no longer repositories, but the most important factor isn't just adhering to design patterns in the strictest of senses. It's using the pattern that suits your applications needs, and sometimes that may also come with distorting the meaning of what that pattern implies.
Not every standard or pattern will perfectly fit into your application, nor should it. You should make changes where needed and break convention when appropriate. This is a matter of judgement. If you think it's simpler to use Repositories as effectively collections of advanced access methods (with application logic in another layer like Services), or collections of application logic. Even both.
Background:
I currently have a web application based on MVC Kohana PHP framework, that allows users to sell ebooks to their customers.
The code behind the webapp is all wired together and everything but API-centric.
It is running pure MVC and then using mustache for template system.
What I would like to do:
I would like to integrate various accounting services (from bigger nordic providers like e-conomic.com) but also own integrations that will let users to optimize their selling and so on.
What I would like to archieve is to make something, call it an engine, that allows functionality integrate (flexibely) into parts of the webapplication, whether its in the view-part or controller/logic.
Based on the background and looking at the technical point of view, which ways are there to do this?
My thoughts is that I need some kind of placeholders all over in different areas of the webapplication. Then I need these placeholders to work together with a "engine" that then checks integrations wants to "run" in these areas?
Would that even work? What would you do?
Update trying to make it more clear:
So what I would like to accomplish is to have separate functionality that would integrate into the existing main webapplication.
Let's just say I have a folder called integrations/ and in here there is two different integrations that affect different parts of the system.
The first is a Kashflow (accounting software) integration, that grabs some data from our system and send to Kashflow (API way, fine) but also inside my webapp under "orders" states whether it has synced to Kashflow yet or not. (this is the part the question is about)
Another integration could be a "Featured Ebook" integration. This simply lets you pick what product should be featured and then on the ebook store, the featured product will be highlighted with a orange border around it and some bigger text. (this is the part the question is about)
How are the bold marked working? A webshop provider like Shopify has Apps which does this, and all other SaaS with Apps have this technical solution.
I wonder is it? How can I allow separate functionality affect a base webapp?
I hope it got more clear now.
New update:
What I look for answer is an answer based on the above stated background, how I can implement a solution that would allow this from where I am now.
A good answer would be one that also in text / pseudo way could give a description on how one of the example plugin/integrations i mentioned could be implemented.
So how does the integration communicate with the main application, what does the main application have in order to accept/allow functionality.
Let me start from the very beginning.
What you are looking for is called a service layer which should be implemented in your applcaition. What it does is
Defines an application's boundary with a layer of services that
establishes a set of available operations and coordinates the
application's response in each operation.
Enterprise applications typically require different kinds of
interfaces to the data they store and the logic they implement: data
loaders, user interfaces, integration gateways, and others. Despite
their different purposes, these interfaces often need common
interactions with the application to access and manipulate its data
and invoke its business logic. The interactions may be complex,
involv-ing transactions across multiple resources and the coordination
of several responses to an action. Encoding the logic of the
interactions separately in each interface causes a lot of duplication.
A Service Layer defines an application's boundary [Cockburn PloP] and
its set of available operations from the perspective of interfacing
client layers. It encapsulates the application's business logic,
controlling transactions and coor-dinating responses in the
implementation of its operations.
Let me explain it simple terms so you can understand. What you 1st have to do is define a service layer in your application. Since you are going with MVC, this could be another controllers handling all the requests related to this specific task. You can have separate controllers for each couple of operations. At the end your engine will be these set of controllers.
If you are willing to go to next level you can handle all these integration via an ESB(Enterprise Service Bus).
An enterprise service bus (ESB) is a software architecture model used
for designing and implementing communication between mutually
interacting software applications in a service-oriented architecture
(SOA). As a software architectural model for distributed computing it
is a specialty variant of the more general client server model and
promotes agility and flexibility with regard to communication between
applications. Its primary use is in enterprise application integration
(EAI) of heterogeneous and complex landscapes.
If you need more information let me know.
Update
There are well documented blog posts. Please see the links below.
How essential is it to make a service layer?
Service Layer Guidelines
Based on your update, I think you describe a good case for a web application that needs to become modular. You want to be able to easily add new modules (plugins) that give you different functionalities without having to change the application core each time.
Below is a possible solution to your challenge from conceptual point of view. My intention is to help you grasp on the idea and get you started. Keep in mind that it can be simplified further or become much more complex, depending on your needs.
The theoretical side of things
Plugins/Modules
Each plugin will enable a set of specific features and must be able to work independently from other plugins that are enabled at the moment. All plugins will have to follow a common set of rules and conventions in order to be recognised by your application. This will simplify future maintenance and extension immensely. For example, each plugin should:
Have its own subdirectory under the Plugins/Modules folder that follows a predefined structure (e.g. Backend/Portlets/InstallScripts, etc.)
Use separate storage sandbox in your database, dedicated only to this plugin. Take Kashflow – all tables that are used by the plugin can start with a ksflw_ prefix.
Bring its own partial Frontend view presentation(s) (along with underlying controller logic and model) that implement specific sets of functionality (for example, display pre-selected books in orange border)
Bring its own partial Backend view presentation(s) (along with underlying controller and model) that handle in the site backend (in the case of Kashflow you have portlet visualization that maybe renders a button to manually do synchronization, enables you to schedule one and displays the datetime of the last synchronization made)
Have an installer script, that creates tables, inserts menu items, and initialises hook subscriptions (see next bullet)
Initialize Hooks subscriptions – All subscribed Plugin functions get called whenever a registered event occurs somewhere in the system.
Core functionality changes
You will need new functionality in your existing application in order to start supporting plugins.
Plugin manager – GUI that allows you to install, remove, enable/disable plugins and allow access to them for your clients.
Partial views manager – allows users to select which partial views of which plugins get displayed in what existing placeholders (this will work in conjunction with hooks)
Placeholders for partial views on pages in the places you want to enable your users to display plugin UI and information
Hooks throughout the application – Whenever "interesting" event happens, the system checks if any plugins are currently subscribed to this event and calls/notifies them, then displays the result. Some examples of events that deserve Hooks might be:
Placeholder rendering – this will trigger all subscribed functionalities to display a frontend/backend partial view
Specific business events – e.g. Whenever new book is being added to the catalogue or is being sold
Administration menu rendering – On this event each installed plugin will select all menu items in the PLUGINNAME_AdminPluginMenu table (the plugin should have created this table at install time) and return all them to the hook for displaying.
I'm sure you'll think of other relevant events, as you know your case best of all.
The practical side of things (based on the second update of the question)
1. Leveraging HMVC for visualisation of partial views (widgets) inside of existing views
As I already stated earlier, Kohana supports HMVC or Hierarchical Model View Controller pattern. This means that you can have a hierarchy of controllers like so (already described in the following question):
Now, this enables you to easily call controllers from other controllers and even directly from your views! And it works wonders when you need to embed widgets.
You can make a slight modification to boostrap.ini in order to enable Routes like widget_controller/controller_action/action_parameter (this is described in detail in the tutorial I'm giving you below). Then you can have the following code inside your main view template where you want to render your orange book box:
<div class="widget_sidebar">
<?php echo Request::factory('widget_orangebook/display/3')->execute(); ?>
</div>
When executed, this acts as a hook and will invoke the widget_orangebook controller's action_display method with parameter 3 - e.g. you want to show 3 books.
The controller's action will look something like this:
public function action_display ($number_of_books){...}
As a result inside the <div>, you will see the content of the template set by the widget_orangebook controller after execution of the action.
In a sense it gives the illusion of an AJAX partial rendering, but its being executed on the server without the extra call. It is pretty powerful, and I think this is the way to go for the cases you described.
You can see this tutorial to see a detailed description on all the modifications you need to do. It's a bit fancier - it's about rendering multiple widgets in a widget section, but it follows the same logic.
Note that if you insist on using mustache and logicless templates, you can also do this kind of Request call in the controller, set the result to a variable and then pass that variable to your mustache template.
2. Kohana Modules
Kohana supports modules, that allow you to pack up your plugins in an organized way. As you implement more complex plugins this will become important. You can see more on Kohana Modules here.
I've 3 projects and the mostly need the same models, and the data. So I'm thinking to create a Core app that have Core models(User, Store, etc.). And create different apps for each project. Besides they use the core models, they can have their own models. So what's the best way to do this?
I left this as a comment but it is a potential answer to this question.
Original comment
You might want to look into an HMVC package for Laravel. The only decent use case for it is multi sites using the same core code. This would let you have multiple sites with a core code base using internal cross controller requests from the site controllers to the core code
HMVC or Heirarchical Model View Controller, as a concept extends the MVC pattern and allows developers to make cross controller/route requests. In theory this would allow for x number of sub installations of Laravel (using a package like this) to call a single common ancestor application that would provide them with an API for dealing with specific requests.
This is good as it provides separation of the api/master app and its child application instances, leaving them free to implement their own logic.
I think this may be something that would help you in this instance (and isn't difficult to use).
I have different questions about a full architecture idea. I hope someone with great experience could help me out because I am pretty much getting stuck in all possibilities.
I'm planning to rewrite a community website. Our customer wants to make use of native mobile apps in the future. So I will need to take this into account. Because of this I have decided to create a 100% REST API architecture based on the PHP framework Kohana. I have choosen Kohana because this makes scaling the internal API to a other server very easily without much extra effort. (Kohana threats internal url requests not as HTTP so there isn't much overhead in the beginning and can scale to HTTP with some minor code changes).
At first the API will be private, but later on we might make it public to let more services connect to us easily.
De basic REST structure is as follow:
/cats
/cats/1
/cats/1/custom
'custom' could be 'childs' for instance.
same goes for:
/ads
/bids
/users
/banners
etc..
These are perfect entities for the API because the mobile app will definitely use all this functionality.
So we can conclude the core of the website is REST. So basically I want to make the website a client of the API just like the native app in the future. This way maintenance seems much easier.
What worries me though is the fact that there is much more than this (managing uploaded files, invoicing, automails for invoicing, automails for ads and so on). Uploading files needs to go through the website to the API. Is this common practice? If I do not do this, the website would do upload logic, which makes the site no client anymore and the app itself. Hence the mobile app can't even upload and both API and website need to know the upload folder (duplicate logic).
I thought of creating the following modules:
community-api
community-website
Api seems to be the core then. But.... what about cronjobs etc? Actually they should not be part of the website, as this is just a 'client'. I feel they should interact directly with the model or API. So basically the API gets more like a gateway to the core and thought I need this:
community-core
Models
Cronjobs
Auto Mailings (part of cronjobs)
Invoices etc
community-api
Interact with models in core through HTTP
community-website
Website
Admin
The core cronjobs are a exception to the REST structure. They are the only one that can change data without going through the api. At least that was my idea because they belong in the core and API is on top of the core.
But by design that seems just wrong. Manipulating should only go through the API!
Alternative:
community-core
Models
community-api
Interact with models in core through HTTP
community business
Cronjobs
Auto Mailings (part of cronjobs)
Invoices etc
community-website
Website
Admin
This look better by design to me.
(source: mauserrifle.nl)
Main Questions
1)
Should cronjobs manipulate through the API or Core models?
2)
My invoice cronjob needs a template pretty much the style of main website of course. But if my cronjob is part of business or core it won't have knowledge of my main website. What makes sense to solve this?
3)
My website will be using mustache as a template engine. (both php and javascript can parse these templates). I thought using the api directly for ajax calls but then realized:
The site gets data from api, formats timestamps to dates (Y-m-d) for the template and then renders. If I let javascript call the api directly, javascript must have logic too (formatting). This is duplicate code! Feels like the only solution is calling the website for ajax (which calls the api and formats) and returns the formatted json. Am I right?
But.... simple calls like deleting a ad can go through the api directly (e.g. DELETE: /ads/1
I get a mix of calls....
Any better solution for this?
4)
Overall: Is my architecture too complex? Any alternatives I should consider?
I would love to hear your feedback!
Once I've heard that a good way to develop a web application is to develop an API-Centric Web Application. The thing is, to me, if you couple the main service to the public API, building an API-Centric application, you lose the whole point of developing a public API at all.
This doesn't seem logical to me.
Yes, the API and the website and what ever might come next are separate things and website should be a client to the API itself but since it will simplify things greate, I believe that you should RE-USE the domain-classes to build and base your web-site logic. This way you can use all the same code base and handle all your issues including ads, invoicing and of course file uploads with ease.
For the public API, it should be on a separate box if possible re-using the same domain classes but with different authentication methods so that whatever problem might occur, it won't affect the main service.
Your cron-jobs should only be used to fire the call through the API itself and those calls should be made on the main app (website through the API)
If you build your website without repeating-yourself, as in, using the same code as the base and wrapping the web-app around it, you won't have the issue raising in q#2.
Same thing applies for question number 3. If you wrap the website around the API, the website can use the api itself without being a separate entity.
Your architecture seems complex but if you do these things, it will be simple. ;-)
Good luck!
REST is just one way to initiate a request. Your core code that processes the request shouldn't be tightly coupled to the REST interface, or HTTP for that matter. I would advise designing your REST API as a simple mapper to an include file or something similar. Your cron could then bypass the whole REST API and just include the file directly. Separate the request interface from the code that does the actual processing.