[WIP] Refactor response/request #145
[WIP] Refactor response/request #145
Conversation
I'm actually already reworking all this stuff. This PR will cause some pretty big conflicts with what I've got so far. :) |
I'm waiting for your PR :) |
Fair warning - it's a doozy! :) But now that the master branch doesn't have to be perfect, if @gfosco merges it in, you can add your stuff and we can play code ping pong! :) |
I think it's better to wait for your PR before considering merging mine ;) |
@SammyK I'll be happy if you include my changes in your PR :) |
So... are we looking to merge this or close it? My time is still super limited for the next week or so, just fyi. |
Waitin' for @SammyK 's answer... |
Sorry guys! Almost done with the refactor, but I've been sightseeing at the Grand Canyon so I haven't been able to finish it off yet. I should be back online to a steady internet connection by this weekend. :) |
FYI - finally back in the saddle! Gonna start finishing #141 off. :) |
👍 |
EDIT : As I said in my comment, this is how I think the refactoring shoud be. End-user APIInitialisation// A FacebookApplication entity
$facebookApp = new FacebookApplication($appId, $appSecret);
$appAccessToken = $facebookApp->getAccessToken();
// A Graph API object that handle requests
$graphApi = new FacebookGraphApi([$httpClient, $version, $beta]); // or just Facebook :)
// with getters/setters for optional parameters
// Get an access token from a helper (or eslewhere, like database), e.g. with FacebookRedirectLoginHelper
$helper = new FacebookRedirectLoginHelper($graphApi, $facebookApp);
$accessToken = $helper->getAccessTokenFromRedirect(); Usage// Manual
$request = new Request($accessToken, $endpoint[, $method, $params, $eTag]);
$response = $graphApi->handle($request);
$obj = $response->getGraphObject();
// Shortcuts
$obj = $graphApi->get($accessToken, $endpoint[, $params]);
$list = $graphApi->getAsArray($accessToken, $endpoint[, $params]);
$graphApi->post($accessToken, $endpoint[, $params]);
$graphApi->delete($accessToken, $endpoint[, $params]); Batching// Manual
$batchRequest = new BatchRequest($accessToken /* or null */, $requests /* array of Request */);
// or
$batchRequest = new BatchRequest($accessToken /* or null */);
$batchRequest->add(new Request(/*...*/)[, $name, $dependsOn, $omit]); InternalGlobal
Service
EntitiesAll entities are value object, immutable.
Optional : Builders, can be added laterAllow fluently create a request or a batch request and execute it
$facebookApp->request($graphApi)
->withAccessToken('access-token')
->withFields(['foo' => 'bar'])
->withETag('some-eTag')
->get('/foo')
->send();
$response = $facebookApp->batch($graphApi)
->newRequest()
->withAccessToken('access-token')
->get('/me?fields=name')
->newRequest('access-token', 'request-name')
->get('/me/feed')
->send(); |
Nice - I wish we could have sat down at a cafe to chat about the refactor! :)
$response = $facebookApp->batch($graphApi)
->newRequest()
->get('/foo')
->newRequest()
->get('/bar')
->send(); Since $batchRequest = $facebookApp->batch($graphApi);
$batchRequest->newRequest()->get('/foo');
$batchRequest->newRequest()->get('/bar');
$response = $batchRequest->send(); That is how it works in #159. All in all, this has some nice improvement on #159 and also contains a lot of the same features. As far as implementation, I can fix the conflicts on my PR and @gfosco could merge it to |
Thanks!
$response = $helper->batch()
->get('/foo') // start new request
->withAccessToken(...)
->post('/bar') // adds the above request and start a new one
->withParams(...)
->send(); // add the last request and return a BatchResponse Note the usage of the helper instance, it make more sense Thanks again for your thoughts @SammyK. About how to merge our PRs, its depend on which implementation @gfosco prefer. Let's wait for @gfosco thoughts. |
UPDATE:
$helper = FacebookRedirectLoginHelper::create($appId, $appSecret[, $httpClient, ...]);
$graphApi = $helper->getGraphApi();
$facebookApp = $helper->getApp();
// With requests builders
$response = $helper->request()->...->send();
$batchResponse = $helper->batch()->...->send();
|
I think our PR's are more similar than you think. I can take all the magic stuff & collection/graph object casting and move it to a separate PR. Then there won't be much difference between your PR and mine. The main difference would be that mine tends to focus on making things accessible via It'd be cool to have $helper = Facebook::newRedirectHelper();
$helper = Facebook::newJavascriptHelper();
$helper = Facebook::newCanvasHelper();
// and all the things
$graphHandler = Facebook::newGraphHandler(/* ...args... */); // returns FacebookGraphApi
$request = Facebook::newRequest(/* ...args... */);
$batchRequest = Facebook::newBatchRequest(/* ...args... */); And I think you'd want to always inject |
We have got the same approch, yours is focused on a new $helper = FacebookRedirectLoginHelper::create($appId, $appSecret[, $httpClient, ...]);
$helper = FacebookJavascriptLoginHelper::create($appId, $appSecret[, $httpClient, ...]);
$helper = FacebookCanvasLoginHelper::create($appId, $appSecret[, $httpClient, ...]);
// and all the things
$graphApi = $helper->getGraphApi();
// same as $graphHandler = Facebook::newGraphHandler(/* ...args... */);
$request = $helper->request()->...->send() // use the RequestBuilder
// same as $request = Facebook::newRequest(/* ...args... */);
$request = $helper->batch()->...->send() // use the BatchRequestBuilder
// same as $batchRequest = Facebook::newBatchRequest(/* ...args... */); From an end user point of view, it's don't make sense to me to have |
The main point of having factories like Again - both ways can be implemented, the And if we tightly couple the factories to the helpers, then it'll difficult to make direct calls to Graph when you already have an access token (from the database for example). Or did I misunderstand? :) |
@SammyK, parameters between square brackets are optionnal! :) Finally, the simpliest way to use this implementation can be: $helper = FacebookRedirectLoginHelper::create($appId, $appSecret);
$response = $helper->request()->...->send(); This will use as default access token the one from the helper About an existing access token, there is the manual way: $request = new Request($accessToken, $endpoint[, $method, $params, $eTag]);
$response = $helper->getGraphApi()->handle($request); but also shortcuts: $response = $helper->getGraphApi()->get($accessToken, $endpoint[, $method, $params, $eTag]); and through fluent builder: $response = $helper->request($accessToken)->...->send(); |
Finally this allow different usage:
$helper = <a helper class>::create($appId, $appSecret);
// without access token, use helper's one
$response = $helper->request()->...->send();
// with already exists access token
$response = $helper->request($accessToken)->...->send();
$helper = <a helper class>::create($appId, $appSecret);
// without access token
$accessToken = $helper->getAccessToken();
// with access token
$accessToken = new AccessToken($helper->getApp(), $value):
// then
$response = $helper->getGraphApi()->get($accessToken, $endpoint, ;..);
// without access token, must use a helper
$helper = <a helper class>::create($appId, $appSecret);
$facebookApp = $helper->getApp();
$accessToken = $helper->getAccessToken();
$graphApi = $helper->getGraphApi();
$response = $graphApi->handle(new Request($accessToken, $endpoint, ...));
// with access token, do not need helper
$facebookApp = new FacebookApplication($appId, $appSecret);
$graphApi = new FacebookGraphApi([, $httpClient, ...]);
$accessToken = new AccessToken($facebookApp, $value):
$response = $graphApi->handle(new Request($accessToken, $endpoint, ...)); But there is no reason to not use the easier way! :) @SammyK Yes I live in France, and no plan to go in the States sorry |
Builders? I'm not sure that is necessary... BatchBuilder less so (I'm still on the side of it just being an array of normal requests). |
Yes builders. They decouple the fluent interface to create requests. They just helpers to easily create requests on top of the core refactor. They are not necessary at a first time. |
Closes for reasons I say in this comment |
Yeah, I love fluent interfaces, but if we add them to the SDK then the Facebook Query Builder could become useless! Lol. So I'm cool without adding them to the SDK. But! I would still like to add factories. More thoughts to come on that... |
They aren't as advanced as your FQB ;) |
Tests still pass!! :) (EDIT: only first commit)
EDIT: see below