-
Notifications
You must be signed in to change notification settings - Fork 182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve "Private App" API usage #151
Comments
Thanks for this – the docs could use a lot of improvement (notably example PHP code for different app types) |
Ah, I can understand now why this library works the way that it does. It's following the upstream Ruby version of the same API library: https://github.com/Shopify/shopify_api#steps-to-use-the-gem From what I can understand this appears to have the same issue. The Ruby API version 9 had better documentation explaining how to use the library for private apps: https://github.com/Shopify/shopify_api/tree/v9#2a-private-apps Going to make an issue request over there to find out if this is intentional or something they plan to fix too... |
On further reading, I am guessing I am slightly "mis-using" the intended API here. It appears the expected behaviour is to create a "session" using Context::initialize, then use the Rest library and pass back in the shop and access token from the session I just made. This does seem a bit overly complex for my use case though! https://github.com/Shopify/shopify-php-api/blob/main/docs/usage/rest.md#rest-client
Created a ticket here Shopify/shopify-api-ruby#911 |
This is still an issue that is not just documentation related. Like @MikeParkin I also believe there is a bug in the code: https://github.com/Shopify/shopify-php-api/blob/main/src/Clients/Rest.php#L46 The Rest Client can not make a HTTP API request when the context has been set to a private app ( A private app is more likely to use an "Admin API access token" that was not obtained through an OAuth created session, and thus does not require the referenced context to be configured anyway. Admin API access tokens should able to be used with the Rest class while the context's I don't even think one can use an "API Secret Key" as the Happy to make a PR, but being new the to lib and the API, I am hoping I am not missing something? |
I am able to do this as a workaround: // initialize the context
$session = new Session(
id:'NA',
shop: $hostName,
isOnline: false,
state:'NA'
);
$session->setAccessToken($accessToken);
$products = Product::all($session); That is with |
Why is Context::initialize a singleton anyway? I might want to communicate with multiple stores in the same PHP thread. |
@lukeholder has the most direct workaround. Docs are severely lacking for private apps with a permanent access token and just in general. This works for private app with permanent access token. use Shopify\Auth\FileSessionStorage;
use Shopify\Auth\Session;
use Shopify\Rest\Admin2022_07\Customer;
Shopify\Context::initialize(
'key',
'secret',
['read_customers'],
'shop',
new FileSessionStorage('your_apps_php_sess_save_path'),
'2022-07',
false,
false,
);
$session = new Session(
id:'NA',
shop: 'shop_domain',
isOnline: false,
state:'NA'
);
$session->setAccessToken($_ENV['PERMANENT_ACCESS_TOKEN']);
$customer = Customer::search(
$session,
[],
['query' => 'email:customer@shop.com'],
); |
This issue is stale because it has been open for 90 days with no activity. It will be closed if no further action occurs in 14 days. |
This should not be closed. |
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days. |
Still shouldn’t close this. |
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days. |
Still shouldn't close this. |
Hi Everyone! Thank you all for this issue, it helped me understanding better how to use this package for private app Open to help on this one! (first time helper here) |
Thanks to all who contributed here, particularly @lukeholder and @Zelfapp - your fixes rescued me from 3+ hours of struggling. I'd been reading all the documentation thinking I must be missing something, because there seemed to be no explanation whatsoever for how to use the api for private apps. Glad it wasn't just me. |
THANK YOU SO MUCH EVERYONE!! I was struggling for 2 hours here trying to figure out how I could use "Access Token / Basic AUTH" to connect to my Shopify Private App created from the admin (NOT PARTNER CENTER APP), as described here: How can the documentation be so bad?? There is no simple example anywhere here, the docs are spread over dozens of confusing pages and I simply couldn't figure it out. Seems like I am not the only one though!! Also, the sample app shopify-app-template-php is a Laravel/React/Nodejs monstrosity that I'm sure it could be useful, but for someone just starting out and trying to make simple API calls, how should anyone be able to figure anything out using that without wasting hours? |
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days. |
Still an issue with the packages PHP API |
Posting this here in lieu of the docs ever being updated (since this is now the second time I've run into this issue and wound up back here trying to solve it). Here's the complete code for using the REST API:
|
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days. |
Issue is still not resolved. |
I'd also agree, using this SDK for any app that doesn't "live in Shopify's admin" is extremely painful. This SDK makes assumptions that you are not using a framework (this SDK tries to handle sessions, key management, etc for you) and generally is trying to do too much. The For admin/develop apps, this SDK makes you set up so much around supporting multiple stores when all you really need is the I honestly feel a re-write or simplified Side note: My comments here are very opinionated but Shopify is the monolith storefront. Having a monolith library is very annoying when you need to interact with one part. EDIT: It appears this complaint is across the board with the Shopify SDKs. Similar thread on the Ruby side of things: Shopify/shopify-api-ruby#911 (comment) |
Are we going to get an update on it? This SDK is useless for most implementations. The API client classes should be extracted from the OAuth, SessionStorage, etc classes. In reality this should be maybe 4 or 5 different packages. One for Rest, GraphQL, OAuth, Utils, and a broiler plate for an app where you can put the basic functionality of the Context class. They are asking for the same thing on the Ruby side. This SDK is unusable. You cannot even instantiate the Rest class and use it without Context being initialized since it depends on the |
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days. |
Definitely not stale and stale bot is useless. |
Not stale. |
Some simple docs would be nice^^ Thanks for this thread 👍 |
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days. |
Not stale |
I was able to access the Admin REST API using this minimal implementation (workaround) <?php
namespace App\Controllers;
use Shopify\Clients\Rest;
use Shopify\Context;
use Shopify\Auth\FileSessionStorage;
Context::initialize(
apiKey: 'your_mom',
apiSecretKey: 'your_mom',
scopes: 'your_mom',
hostName: 'your_mom',
sessionStorage: new FileSessionStorage('/tmp/your_mom'), # /dev/null does not work here
apiVersion: '2024-04',
isEmbeddedApp: false,
isPrivateApp: false,
);
$client = new Rest($_ENV['SHOPIFY_SHOP'], $_ENV['SHOPIFY_ADMIN_API_ACCESS_TOKEN']);
$response = $restResponse->getDecodedBody(); Please note that |
The issue is that method will just break with any background update. The dependency on this Context class needs to be removed entirely. |
Yes, for sure. And that's what the Stateless in REST means. |
It's crazy how long this issue has been open. I'm running into the same issue. Thinking maybe it'd be prudent to just write my own graphQL access using Guzzle client or something. |
Hey everyone. Thank you so much for your patience, and sorry for not responding earlier. The stalebot has been removed from this repo, so that problem is gone. I agree that there is a bug in that line, it should be using a separate config value for that access token, and not the API key. We will fix that and take another look at the documentation for private / custom apps to improve it for apps. Thank you all for the suggestions here. |
I think the bigger issue is this SDK is dictating how to form your app/service. There is no freedom to throw out the Context class. You can't use the GraphQL or Rest clients without implementing the whole thing. IMHO, this SDK is doing too much. It would be much nicer to see it broken into 4 different libraries (OAuth, Rest, GraphQL, Utilities for views/webhooks) and then if you want the "simple implementation" that this is trying to provide, make that a wrapper for all 4. That way, the advanced users can implement how they want and the simple users can use the simplified Context/Session management way. This also needs to happen with the Ruby version as well. That suffers from the same dependencies. |
I decided to use the raw HTTP requests instead of this SDK for now. I only need to read and update inventory with a private app. Will come back later when OAuth is needed to us. Thanks for everyone's comments here, it proves that I am not alone. |
@haoxi911 funny, I did the same thing a month or so ago. In hindsight I wish I never bothered with the SDK. It's been smooth sailing ever since I stopped using it. |
@haoxi911 thanks for your fresh comment. could you submit an example? After some days of completely useless trying, I'm done with messing around. Just need to access product data but can't get a connection to the shopify server. cheers, thomas |
Hi guys..., I'm just saying, thank god I reviewed this issue, I have been struggling with the documentation because it said too much but nothing at the same time. So this is my implementation using Laravel: <?php
namespace App\External\Shopify;
use Shopify\Clients\Rest;
use Shopify\Exception\MissingArgumentException;
abstract class BaseShopifyApi
{
protected Rest $client;
/**
* @throws MissingArgumentException
*/
public function __construct()
{
$this->init();
$this->client = new Rest(
domain: config('services.shopify.store_url'),
accessToken: config('services.shopify.admin_token')
);
}
private function init(): void
{
\Shopify\Context::initialize(
apiKey: config('services.shopify.api_key'),
apiSecretKey: config('services.shopify.api_secret'),
scopes: config('services.shopify.scopes'),
hostName: config('app.url'),
sessionStorage: new \Shopify\Auth\FileSessionStorage(storage_path('framework/sessions')),
isEmbeddedApp: false,
);
}
} <?php
namespace App\External\Shopify;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
class ProductsShopifyApi extends BaseShopifyApi
{
public function list():? array
{
try {
$response = $this->client->get('products');
if($response->getStatusCode() !== Response::HTTP_OK){
throw new \Exception($response->getDecodedBody());
}
return $response->getDecodedBody();
} catch (\Throwable $exception) {
Log::error($exception);
return null;
}
}
} be sure to use this help section https://help.shopify.com/en/manual/apps/app-types/custom-apps to generate all the credentials, scopes, etc that you need to connect with "your" store. |
@paulomarg this is one of the things that needs to be fixed btw in addition to the other bugs. |
@weinraum Here is an example. The tradeoff of using raw HTTP requests is probably composing GraphQL queries by ourselves. You could find the details in the Shopify GraphQL API reference.
|
Overview/summary
Currently using this library when connecting to a private app is confusing.
It takes quite a long time to work out what you are doing, when it feels like it could be really simple.
Motivation
In our usecase, we only want to consume the Shopify admin api via REST, with a private app access token.
Currently to do that you have to have the following code:
This is not helped by the fact that there is a bug on this line:
https://github.com/Shopify/shopify-php-api/blob/main/src/Clients/Rest.php#L46
So you actually have to Context::initialize with "privateApp" to to false, so it uses the access token not the secret key.
There is barely any point in having to call Context::initialize, the only reason for doing it is to:
In an ideal situation I would just need to do this:
Possible Improvements
Happy to contribute these changes, if you are welcome to receive them.
The text was updated successfully, but these errors were encountered: