I've have one question about architecture.
We have api for mobile backed. And now we implementing some new features, like user messaging.
For no api uses one database, and I want to have separate api and database for messages. Like micro-services. api.somedomain.com, messages.somedomain.com, etc.
Main api is guarded by implementing access via access keys. And in micro-services databases I need some data from main database, like user info, profile info, etc.
Maybe someone have ideas how to implement such mechanism?
Maybe master-slave replication with slave = database where I need information from main database?
Maybe you can just create some endpoints in your main API to get the information your want. In your new micro services you can consume this API. I think it's a beautiful design and make you application more agnostic and extensible
Perhaps mapping each database involved as an separated entity manager.
You can map the new services as new container services and new controllers.
Symfony and Doctrine allows you to access different entity managers very easily.
Replication is a good resource, but sometimes it's cumbersome. Maintaining a replica set requires additional efforts and hardware.
You should evaluate if the database is too big or might have some performance issue due the micro services consuming the main database.
Related
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.
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 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.
At my work we have two separate sites that are very closely related. One of them is a ASP/MSSQL site and the other is a PHP/Postgres site.
I want to create a REST API that everything from now on is built on top of. I would like it to be tied to both DBs so that it can be a a single point of retrieving and setting data.
I was thinking of using a DBA like Doctine to keep from writing queries in two different syntax. In the same system is it possible to tie parts of Doctrine to the MSSQL and other parts to Postgres?
If so, how? Any other thoughts on design are welcomed.
Within your application framework, you need to configure two separate entity managers, each of which will connect to a different database. More on entity managers at http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/configuration.html
The core architectural pattern is that your models are plain PHP objects, and the entity manager (Data Mapper) will read the mapping configuration to know how to map the models to a database.
If you're writing a REST based API it shouldn't really matter what the DB backend is. For example, if you write your API in a combination of Django and tastypie, you could simply swap out a settings.py config to work with both Postgres and MySQL... or even MongoDB if you so chose
The point is, a REST API is a generic solution that can be used by a multitude of languages, you should chose a framework that allows you the same flexibility in DB backends to implement.
My aim is to write a collection of many webapplications, like google services (mail, calendar, docs, ...).
It will be written in PHP with Zend Framework (Version 2). I use MySQL to store data.
The service collection should always be extendable (new services) easy.
Is it useful to provide a own database for every service? They would have few tables only (more or less 3). That would mean that I have to use Zend's multiple database adapter.
The other solution is to use one big database for the hole collection. The advantages are that I can use foreign keys between the tables of different applications. I also could use the default database adapter.
All the applications are enmashed with each other close.
What makes more sense?
If you have enough databases from your provider you could use multiple databases, but if you have User accounts its better to create one main-Database for that.
Break the services out with one database each, including the service that identifies the users. All of the services should talk to each other via web services. This architecture will be the most flexible in terms of scaling pieces individually as well as maintaining the pieces individually.
It is impossible to give anything more specific in terms of architecture of such an application ecosystem without substantially more information about the project, and incidentally, that would be beyond the scope of this site to answer.