I'm working on a solution to make certain data from a large database available to a remote website. My first thought was to simply cook up some soap web services to fetch certain data from the database. This could be done in just a few line, for instance like this, with the user of Zend_Soap_Server:
class MyClass
{
public function getlastname($id)
{
$dbh = new PDO("oci:dbname=bigdb", "theuser", "thepass");
$stmt = $dbh->prepare("select lastname from person where id = :id");
if ($stmt->execute(array(':id',$id)))
{
$row = $stmt->fetch();
return $row['lastname'];
}
}
}
$server = new Zend_Soap_Server(null, $options);
$server->setClass('MyClass');
$server->setObject(new MyClass());
$server->handle();
Now someone told me to also have a look at message brokers / queues. I've been taking a look at some software like apache activeMQ, stomp and zend_queue but I didn't really get a clear view what they should be used for and weather they would be useful in this project.
I do understand that my implementation could have some drawbacks, like a sluggish website when the database is not responding quickly and a high load on the database when there are coming lots of requests from the website, would a message broker be able to prevent such complications?
The role of a message broker is to check the requests and dispatch them to the right service or return a response from a cache.
If you are expecting large traffic you probably should consider using a message broker.
Regards,
Alin
Related
I really want to make a rest api project but i can't understand how.
For now i have all the html css and php pages, i have a functional php app with database.
Also i have slim routes tested with Postman and all works(return Json). My question is: how do i link all that parts to make a functional rest api aplication?
My routes looks like that:
$app->get('/api/users', function( Request $request, Response $response){
$sql = "SELECT * FROM users";
try {
$db = new db();
$db = $db->connect();
$stmt = $db->query( $sql );
$users = $stmt->fetchAll( PDO::FETCH_OBJ );
$db = null; // clear db object
echo json_encode( $users );
} catch( PDOException $e ) {
echo '{"error": {"msg": ' . $e->getMessage() . '}';
}
});
I read about several options but i can't understand how all this works. How i get data from forms for example and pass to route and route output the result that i want using data from forms.
Can you suggest me a simple way to do that and all the framework that i need?
If you want a UI (user interface) then you need to build a front-end application - written in Javascript assuming it would be a web front-end (perhaps using one of the popular frameworks such as React or Angular) - which can then make calls to your API via AJAX requests to get data to populate the screens etc. Or you could make almost any other type of application to talk to it
Your API is the backend...it can support having lots of different types of application calling it potentially (e.g. web app, mobile app, desktop app, automated service, IoT device etc) - that's the beauty of separating the core, shared functionality and logic of your system into an API, away from the potential different client-side experiences you might decide to create.
i'm using Slim framework to provide an API to our clients. I'm focused on Java so that could the the point, because the problem is related with database connection.
Every request connect to the database throw PDO like
$dbh = new PDO($param1, $param2, $param3);//php 7.1
So as php don't have a connection pool i understand each request (maybe at the same time) starts a new connection throw the database.
But i'm experimenting a kind of situation here.
If one request starts a transaction for inserting or updating something, next requests will wait until this transaction finish, but it is on a different thread, so i'm thinking on table locks? or something like each request is getting the same connection.
THE PROBLEM:
So if they are in different threads with a different connection how
they need to wait until transaction ends for the first request.
My database source class is something like
class DataBaseConfig {
public static function getConn()
{
$dbh = new PDO($param1, $param2, $param3);
$dbh->exec("set names utf8");
return $dbh;
}
}
And i use it like
$db = DataBaseConfig::getConn();
$db->beginTransaction();
//code
$db->commit();
I'm missing something sure, so can someone help me with this problem?
Thanks!
NEWS! EDIT
#YourCommonSense thank you it was finally a session configuration. I
didn't know that php start_session(); locks the session file so that's
what was happening. Thanks a lot!
link: https://ma.ttias.be/php-session-locking-prevent-sessions-blocking-in-requests/
I am making iOS chat application. After doing study on needed technology and protocols, I decided to give a websockets try. For reasons our stack top is php based and I came to know about ratchet as websockets for PHP. I made simple chat server for ios front-end from reading documentation. Chat is working very fine and I am comfortable with it too. I wanted to know on how to create separate private chat rooms. Will different instance of socket event loop needed to run for separate rooms ?
The sample server I made is using single event loop for managing user connections and dispatching messages to different connection/user id's. I really tried to look out for creating private chat rooms but haven't found any information where I could be confident.
Will I have to manage each connection/user id's virtually on this event loop, like deciding which users can chat to each other directly by controlling the dispatching of messages ? Or is their really a separate way to do this ? This is the event loop sample as per documentation that I implemented:
<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);
$server->run();
I want to tell that I am a iOS/Android developer and really no expert or have fluent knowledge on web frontend/backend technologies.
Will different instance of socket event loop needed to run for separate rooms ?
No. Only one loop is needed. Your snippet is fine. What you have to do is to adjust Chat class so that it accepts additional parameter from the user input - room id/name.
For example, a user sends the message {"cmd":"msg", "message":"Hi", "room": 1}, then Chat should send the message only to the users who joined that room. And, of course, you should implement other user methods, such as {"cmd":"join", "room": 1}, {"cmd":"leave", "room": 1}
Well i might be a little bit late to answer, but here how i did that.
You should implement WampServerInterface instead of MessageComponentInterface on your Chat class (If you are not already doing so).
As said above your snippet is fine.
Here my Chat class :
class Chat implements WampServerInterface
{
protected $conversationId;
public function __construct(){
$this->conversationId = null;
}
public function onSubscribe(ConnectionInterface $conn, $conversation_id){
$this->conversationId = $conversation_id;
echo "Client $conn->resourceId assigned to the conversation : $conversation_id\n";
}
public function onPublish(ConnectionInterface $conn, $conversation_id, $event, array $exclude, array $eligible){
echo "Message sent to $conversation_id : $event";
// ... save in Database or else
// Send data to conversation
$this->conversationId->broadcast($message);
}
}
This is for a connection to one room only.
However if you want to have multiple chatrooms running in same time, you should have a look to Ratchet code on Github.
I don't know what did you use for the frontend, i personally use autobahn.js to instantiate the connection with the server (using ratchet).
The more I read about dependency injection the more I get confused. I know what it is for, that is not the problem. Trying to do some design on paper this is what I came up with and somehow it seems to me I am overlooking something.
First I imagined building an actual server that would accept incoming requests and returns responses to the user.
class Server {
private $responseBuilder;
public function __construct($responseBuilder) {
$this->responseBuilder = $responseBuilder;
}
public function run() {
// create socket, receive request
$response = $this->responsebuilder->build($request);
// send response
}
}
class Response {
private $method;
private $message;
private $url;
// getters & setters
}
class ServerBuilder {
public build() {
// construction logic
return new Server(new ResponseBuilder());
}
}
Since Apache is used to handle server requests we could replace the server with something that just send the response.
$bldr = new ResponseBuilder();
$response = $bldr->build();
// send response some way
Note that ResponseBuilder has direct access to the request ($_SERVER['..'])
and so it has everything it needs to choose the right response.
PHP however allows us to build and send responses inline. So we could have a Controller object for each page or something else that send the response and have a builder for that.
$bldr = new ControllerBuilder();
$controller = $bldr->build();
$controller->run();
class ExampleController implements Controller {
public function run() {
header("HTTP/1.1 404 Not Found");
echo 'sorry, page not found';
}
}
This all makes sense to me. But let's look at the server example again.
It calls $responseBuilder->build() and gets a response back. But this would mean that the builder (or other builders if we split it) is also responsible for anything else that might occur like authenticating a user, writing to the database,... and I can't get my head around the fact that writing to a database would be part of the object graph construction.
It would be like: Send me your request. Oh you want the homepage? I will build you your response and while I'm at it I will also do some things that have nothing to do with building it like logging what I just did and saving some of your data in a cookie and sending a mail to the administrator that you are the first visitor on this page ever, ...
You should decouple them. You have a few assumptions that I think are a bit strange. Let's start with them.
The main purpose of an incoming http request is to give back some html
I have built PHP backends that only return JSON, instead of HTML. I had a really strong border between back and front end. I only used the backend to give me data from the database, or add/edit data in the databse. The front end was just a PHP script that would build the pages any way i wanted.
Since it is the web there is in theory no use for setters since
everything can be injected in the constructor
You could use the constructor, but you don't have too. You can use setters. Dependency injection is actually just turning the flow around.
You are on the right track though. You want some class that is responsible for building your pages. So, make it only responsible for your building your pages, and take out the other responsibilities. Things like logging, authentication etc should be outside of that.
For instance if you want logging, you could have your builder create your page, and your logger could then listen to all the things your builder is doing (with the observer pattern for instance). So if your builder says: "i created the home page", you can log it with your logger, who is actually listening to your builder.
Authentication for instance should happen even before your builder starts. You don't want your builder to go to work if you can already figure out that a user is not supposed to be on a page. You could use a database for that, and whitelist any usertype/pagerequest combination.
Then for data handling, i would create a backend, that only handles requests that are supposed to give back data, or save it. The front end could then communicate to get it's content by pulling it.
I hope this clears up a few things, but I'll be happy to answer more indept questions.
i,m trying to write a trigger in SalesForce Opportunity which have to send the updated StageName to external webservice using predefined username and password.
here is sample code:
trigger isStageChanged on Opportunity (after update) {
for (Opportunity o : Trigger.new) {
Opportunity beforeUpdate = System.Trigger.oldMap.get(o.Id);
if(beforeUpdate.StageName != o.StageName) {
// Call WS
}
}
}
"Call ws" means to use link like:
http://mydomain.com/webservice/index.php?username=MY_USERNAME&password=MY_PASS&stage=opportunityNewStage
The question is: Where can i store MY_USERNAME and MY_PASS in case i want to use this trigger on different SalesForce customers and to let them configure them after install?
When i red the APEX Code Developers Guide i red that i can use a Web Services API to deploy my trigger and that way i can store user and pass on my server. Is it possible?
On my server i'm using php.
I hope i am clear in my question.
You should probably store the username and password using custom settings. This will allow their administrator to easily configure the username and password with values they provide.
Note that you can't make a callout from inside a trigger as it holds up database operations, instead you need to put your callout in a public/global method of another class, using the #future annotation:
#future public void DoMyCallout(list<id> liOpportunities)
{
// load your oppties if need be, then do the callout
}
#future indicates that this method will run asynchronously, so you can call it from the trigger but it will run in another thread and so not hold up the database operation in progress.