Build web app functionality behind an Api - php

I have to prepare a specification to provide a road-map for developers to build an in-house project.
The project will consist of a web application and a mobile application.
The mobile app will be used to collect user feedback, typically the mobile app shall display a couple of questions for the user to answer.
Example questions show below;
Did you use shoe polish to clean your shoes ?
Did you watch the news at night ?
The data captured will be sent to an sql server.
The web app shall be used to publish the questions to the mobile app, the web app shall also be used to view reports.
The web app shall have below features;
1. Publish surveys to the mobile app, this could be done by MQTT,AMQP or similar protocol.
2. View data in chart form
3. Manage devices, like enrolling new mobile devices e.t.c
What is needed
This project will be spit and assigned to 3 teams, the backend team(Api team) , the frontEnd team and the Mobile developers team.
The functionality of the backend is supposed to go into an Api, the front end should always talk to the backend for getting data, basically no business logic is allowed to go into the front end side of things. The front end will only write css/html/js for markup & presentation, the rest of the functionality should be consumed through an Api.
I have to write a detailed specification of how the project should be implemented, the back-end will be implemented in PHP with symphony. The front-end can be any JavaScript framework, the mobile app will be implemented in Android.
Can you should how i should model the back-End(Api) so that it contains all the functionality needed in the web app ?
On top of that, building the functionality on top of an api a good strategy for this project? Should i go the monolithic way as having the front end and back-End attached together(this will make it difficult to have one developer working on the front end and another one on the back-End/api ) ?

This is a perfect application for a CQRS back end, fed by a queue. With CQRS the write side and read side of the back end are separated into distinct APIs which is especially advantageous when splitting a project among multiple teams.
The main idea of CQRS is that there is a single API to make any changes to data, and changes are made to data via a Command, then persisted to the normalized DB by the Command. There are also physical tables custom designed to contain all data necessary for a single view (these tables are denormalized). Each time data is written to an Aggregate, the appropriate View Models are also updated. This results in a structure where the write side is complicated but has all business logic and rules, whereas the read side is very simple and basically just executes a “select *” query from the appropriate view model table. As long as the read model (also called a projection) is kept up to date the reads are much faster and since the majority of the DB access is reads, the entire site is faster.
In your case I would create 3 APIs – one for the Read Model for the Mobile front end, one for the Read Model for the web front end, and one for the Command side. That way the mobile guys have the flexibility to build what they need, and they can change the read model table design as necessary during development to satisfy requirements. The Web guys can do the same, and the Backend team implements the hard stuff – the commands, business rules, normalized table structures, etc. Merging the three projects would entail having one of the teams create queries to update the view model tables from the entity tables.
All this becomes even easier if you introduce an event based communication architecture, i.e. Event Driven Architecture. This would further decouple the 3 different concerns and make them even easier to merge later since each microservice would subscribe to appropriate messages to receive updates and new cache information.

Related

Use a subdomain to access a portion of a web application (Symfony)

I'm building an application in Symfony which can be identified by two distinct portions.
The first is a portion that handles front facing information to users
The second is the heart of the application that is driven by a number of CRUDs, management interfaces and controls to manage the front end
Currently, the two components sit with the following domains structure
Front end interface: www.example.com
Backend admin interface: www.example.com/app
Ideally, it would be nice to address the admin interface as admin.example.com.
I've thought about using vhost configs to create a reverse proxy from admin.example.com to www.example.com/app however I feel like this is a messy approach.
I've also explored the host option in the #Route annotation within Symfony, however this is also very messy as I need to define this (and a number of supporting default and requirement options) in each controller.
The core reason behind running the same application is that I'd like to have both halves of the application driven by the same database and the same Symfony entities. I understand that I can build two separate applications and this would solve my issue, however this would then create two separate sets of entities between the two projects and ultimately the potential for errors down the track. I would like to avoid having separate applications if I can.
Thanks in advance!
I've come up with a solution to something with this kind issue. Posting my own response in case any one comes across a similar issue and would like to know how I went about it.
As I mentioned there will be an admin control interface and a front end interface. They will both look very different however one will be more application based (admin) and one will be more information centric (front end website).
I have opted to use two separate applications. However making using of the FOSRestBundle I am exposing basic information in the form of a simple API that will be driven to drive a snappy and responsive front end using information from the back end component of the application. The front end doesn't need to be a Symfony application, just something that can render content from the API (either generated server side, or a secondary request post page load via JavaScript - whichever is more fitting).
While this isn't exactly what I was initially envisioning at first, I realise this is the better approach as it would have made the application much more bloated and difficult to maintain over time as the application grew. It will also be rather easy to create a number of simple tests to assure that the data provided by the API is as the front end expects, to avoid any issues as the back end is developed.
Hope this helps anyone!

how to access Symfony's data / business layer from 3rd party apps

I have te following architectural scenario which doesn't depend on me and I can't change:
On one server/machine has several php applications and a postgresdatabase: each application uses its own schema in order to separate applications'data logically. I'm developing a new application - the one represented by the A - using Symfony, which manages and stores data that should be partially accessible by other apps, especially by an old app that's not been developed with symfony nor any other framework. To make it simple you could imagine A app storing movies sent from clients by means of its REST API. I would like B, and C accessing movies' data: B ocasionally should need accessing all the movies with a certain actor acting in it, and C would like to update the owner studio (or vice versa). Of course it would be an A's job, the symfony app that was born exactly for that purpose. SO I thought I have two ways, represented by the arrows:
A's exposes some way an API that B can call. That way I don't have to duplicate business logic and data persistence. Maybe by exposing Doctrine's entities or a controller in some way. Of course I should load at least doctrine, the container, the configuration the httpframework component and when it comes to using C I guess this solution would be unfeasible because I would have two apps using and loading most of the same classes, without any kind of isolation between the two. Another (extreme?) solution I thought is not using Symfony for exposing my A functionalities to the other apps: I could write an API class that connects to the DB and does some logic without any Symfony's support (PDO and friends. No services, no components, nothing.). Luckily what I have to expose is little and that wouldn't be that big problem.
Finally, I would avoid calling A by means of the shell (i.e. app.php console/getMovie) because it consumes tons of resources and I don't think it's that fast. My server is really small and couldn't live up to that
B and the other apps could access A's schema, but that way I maybe should duplicate some business logic and I see it kind of messy. Maybe C app could simply uses an A bundle I could write, explicitly written to expose some A's functionalities 3rd party apps need.
These are the two solutions I've found, but I do appreciate how you think I should design this.
It is possible to share data between schema by using views in a common place (usually public schema).
This has several advantages:
it lets you use your schema structure the way you want.
it exposes the data you want.
it lets you manage the write accesses you want (yes, views may be writeable)
it makes you able to deal with GRANT/REVOKE easily.
it makes the applications able to leverage Postgres` LISTEN/NOTIFY feature to communicate.
There are downsides:
Updating a view means deploying new model files on all the applications using it. It can be a project on its own that the other applications depend on through composer.

Create "Engine" to allow integrations to main web application?

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.

CakePHP - How to setup multiple apps/portals that use same functionalities

We are building a intranet web application in PHP with CakePHP.
However we have barely experience with CakePHP
Our Intranet will have two user portals.
Employee portal
Client portal
Both portals will use the same data but have their own user interface.
Employees can see other data than clients and vice versa.
We want to build a central core for both portals. For example, a single authentication system, a contact form, a notification functionality, same footer information, etc. We want to use this central core as much as possible so we don't have to rewrite code.
We use Git to manage our code. We want to make a branch for both portals and one for the shared core.
We hope you can give us some advise about how setting this up with CakePHP.
Is building multiple app's a good idea?
Or should we just run CakePHP and our core on two web servers? (one for each portal)
Or should we use plug-ins for the core functionalities?
Or should we use single controllers with multiple views (one for employee and one for client?)
Or something totally different?
Thanks for any advice
Eventually, you'll start noticing similarities between the 2 portals, and the code-base. If they are sharing same data, why don't you have a single code-base and have permissions around what users can see based on roles? We had to do this recently when we merged 3 pages into 1. 1 page was for admin, and the other 2 was for other roles. Then users started requesting features on page 2 that page 1 already has etc etc. it became a mess and we decided to consolidate these pages into 1, and have permissions around what each users can see based on their roles. Also read more about helpers as it will come handy, so you dont make your view bloated.
In my experience a portal is typically a very thin layer on top of some CRUD framework. I think the opportunity for code sharing between these two applications is very limited. You can share the authorization and authentication .. and that's about it and I don't know if sharing this part is a good idea (probably not).
If most of your code goes into building the HTML views you'll likely end up with two completely separate views for employee and client.
As Ayo mentioned... the permissions alone will separate the two user groups and you can take advantage of CakePHP's layout or the themes feature to give a totally two different look for each user group.
You may also want to take a look at CakePHP plugins feature. It allows you to easily add new functionalists to an existing app, without messing with the existing code base.

Website prerequisites to create native smartphone app

I'm creating a website in PHP and mysql. I plan to create a native smartphone app for it in the future. The app will allow users to interact with my website's database and receive notification when new data is posted to their accounts. What should I implement in my website while anticipating a future mobile app for it?
I have been creating the same type of system for a few customers of mine. I have built them a website where there customers for example, make a hair cut appointment, that then sends a notification to the hair stylist notifying them of the new appointment information. Is this something similar to what you are looking for?
Also if so, i need to know what language you will be coding the phone app in. I suggest using Java if your going to be learning a new language to do this.
As for needing to implement anything prior to actually creating the mobile app. Thats not necessary.
When you create your native app, you are going to want to access your business logic and database via an API that you create. So when you are developing your website, you really want to think in terms of a MVC (model-view-controller) architecture. Ideally, both your website and mobile app will share the same model and controllers, and you will simply implement the views (very) differently in each.
For example, when you do a login on the website or in the app, you want it to call the exact same code base on the server (and pass the exact same parameters) to process the login. Therefore, make sure to decouple your business methods (controller logic) from your presentation layer when you design the site and always think in terms of "should this functionality be exposed in my API or is it website only presentation".
If you do this now, it will save you a lot of pain later.

Categories