Skip to content

Commit 576d19a

Browse files
committed
Merge branch 'release/1.1' into 'master'
Release/1.1 See merge request yuanwq/shopify4j!36
2 parents d836987 + f91648a commit 576d19a

File tree

47 files changed

+9058
-150
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+9058
-150
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ build
33
gen
44
out
55
.idea
6-
store.properties
6+
test.properties
77

88
# Ignore Gradle GUI config
99
gradle-app.setting

README.md

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Java SDK for Shopify APIs, including:
77
* GraphQL Admin API
88
* GraphQL Storefront Schema
99
* GraphQL Storefront API
10+
* GraphQL Partner Schema
11+
* GraphQL Partner API
1012
* [INCOMPLETE] REST Admin API Models
1113
* [INCOMPLETE] REST Admin API
1214
* ...
@@ -29,13 +31,23 @@ implementation("xyz.codemeans.shopify4j:graphql-admin-schema:1.0")
2931
```
3032

3133
GraphQL Storefront
34+
3235
```groovy
3336
// api
3437
implementation("xyz.codemeans.shopify4j:graphql-storefront-api:1.0")
3538
// schema
3639
implementation("xyz.codemeans.shopify4j:graphql-storefront-schema:1.0")
3740
```
3841

42+
GraphQL Partner
43+
44+
```groovy
45+
// api
46+
implementation("xyz.codemeans.shopify4j:graphql-partner-api:1.0")
47+
// schema
48+
implementation("xyz.codemeans.shopify4j:graphql-partner-schema:1.0")
49+
```
50+
3951
REST Admin
4052
```groovy
4153
// api
@@ -102,12 +114,12 @@ OauthAccessToken accessToken = oauthFlow.exchangeAccessToken(app, redirection);
102114
HMAC Verification
103115

104116
```java
105-
boolean verified = HmacVerification.verifyHmac(queryString, app.getClientSecret());
117+
boolean verified = HmacVerification.verifyQueryString(app.getClientSecret(), queryString);
106118
```
107119

108120
## Multi-Stores
109121

110-
If you are integrating with multiple shopify stores in one sysmtem, just like we do, `StoreFactory` will be very helpful.
122+
If you are integrating with multiple shopify stores in one sysmtem, just like we do, `ClientFactory` will be very helpful.
111123

112124
If information of your stores is saved in some persistent database, you can just implement a `StoreSettingStorage` to retrieve data and build out a `StoreSetting`.
113125

@@ -117,9 +129,9 @@ Here is an example for REST & GraphQL API:
117129
StoreSettingStorage settingStorage = ...;
118130

119131
GraphqlInvoker invoker = new OkHttpGraphqlInvoker(new PrivateAppAdminAccessTokenProvider(settingStorage));
120-
StoreFactory<GraphqlAdmin> storeFactory = new DefaultGraphqlAdminFactory(settingStorage, invoker);
121-
storeFactory = CachedStoreFactory.of(storeFactory); // cache created stores, avoiding duplicated creation
122-
GraphqlAdmin store1 = storeFactory.getStore(domain1);
132+
ClientFactory<GraphqlAdmin> clientFactory = new DefaultGraphqlAdminFactory(settingStorage, invoker);
133+
clientFactory = CachedClientFactory.of(clientFactory); // cache created stores, avoiding duplicated creation
134+
GraphqlAdmin store1 = clientFactory.getClient(domain1);
123135
```
124136

125137
## Release
@@ -136,11 +148,13 @@ GraphqlInvoker invoker = new OkHttpGraphqlInvoker(AccessTokenProvider.constant(s
136148
GraphqlAdmin admin = new DefaultGraphqlAdmin(setting, invoker);
137149

138150
// get a product with: title, handle ...
139-
QueryRootQuery queryRootQuery = Operations.query(
140-
query -> query.product(id,
141-
product -> product.title()
142-
.handle()
143-
...));
151+
QueryRootQuery queryRootQuery = Operations.query(query -> query
152+
.product(id, product -> product
153+
.title()
154+
.handle()
155+
...
156+
)
157+
);
144158
Product product = admin.query(queryRootQuery).getData().getProduct();
145159
~~~
146160

@@ -154,8 +168,9 @@ You can customize your implementation on any http library you like.
154168

155169
## Reference
156170

157-
* GraphQL Admin API Documentation: https://shopify.dev/docs/admin-api/graphql/reference
158-
* GraphQL Storefront API Documentation: https://shopify.dev/docs/storefront-api/reference
171+
* GraphQL Admin API Documentation: https://shopify.dev/docs/admin-api/graphql/
172+
* GraphQL Storefront API Documentation: https://shopify.dev/docs/storefront-api/
173+
* GraphQL Partner API Documentation: https://shopify.dev/docs/partner-api/
159174
* Starter Tutorial: https://www.shopify.com/partners/blog/getting-started-with-graphql
160175
* Codegen: https://github.com/Shopify/graphql_java_gen/
161176
* Find GraphQL schema: https://community.shopify.com/c/Shopify-APIs-SDKs/Admin-API-Graphql-shema-endpoint/m-p/837807

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ buildscript {
3535
// git version
3636
apply plugin: "org.ajoberstar.grgit"
3737
int commits = grgit.log().size()
38-
version = "1.0"
38+
version = "1.1"
3939
String pubRepo = rootProject.hasProperty("pub") ? rootProject.property("pub") : "nexus"
4040
if (pubRepo != "oss") {
4141
version = "${version}.${commits}"

graphql-admin-api/src/main/java/codemeans/shopify4j/graphql/admin/GraphqlAdminFactory.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package codemeans.shopify4j.graphql.admin;
22

33

4+
import codemeans.shopify4j.core.base.ClientFactory;
45
import codemeans.shopify4j.graphql.GraphqlInvoker;
5-
import codemeans.shopify4j.core.store.CachedStoreFactory;
6-
import codemeans.shopify4j.core.store.StoreFactory;
6+
import codemeans.shopify4j.core.base.CachedClientFactory;
77
import lombok.Data;
88
import lombok.NonNull;
99

@@ -12,7 +12,7 @@
1212
* @date: 2021-01-12
1313
*/
1414
@Data
15-
public class GraphqlAdminFactory implements StoreFactory<GraphqlAdmin> {
15+
public class GraphqlAdminFactory implements ClientFactory<GraphqlAdmin> {
1616

1717
private final GraphqlInvoker graphqlInvoker;
1818
private String apiVersion = "2021-01";
@@ -22,17 +22,17 @@ public GraphqlAdminFactory(@NonNull GraphqlInvoker graphqlInvoker) {
2222
}
2323

2424
@Override
25-
public GraphqlAdmin getStore(String myshopifyDomain) {
25+
public GraphqlAdmin getClient(String myshopifyDomain) {
2626
return new DefaultGraphqlAdmin(myshopifyDomain, apiVersion, graphqlInvoker);
2727
}
2828

2929
public CachedGraphqlAdminFactory cached() {
3030
return new CachedGraphqlAdminFactory(this);
3131
}
3232

33-
public static class CachedGraphqlAdminFactory extends CachedStoreFactory<GraphqlAdmin> {
33+
public static class CachedGraphqlAdminFactory extends CachedClientFactory<GraphqlAdmin> {
3434

35-
protected CachedGraphqlAdminFactory(StoreFactory delegate) {
35+
protected CachedGraphqlAdminFactory(ClientFactory delegate) {
3636
super(delegate);
3737
}
3838
}

graphql-admin-api/src/test/java/codemeans/shopify4j/graphql/admin/ContextForTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package codemeans.shopify4j.graphql.admin;
22

33
import codemeans.shopify4j.core.auth.PrivateAppAdminAccessTokenProvider;
4-
import codemeans.shopify4j.core.store.CachedStoreFactory;
5-
import codemeans.shopify4j.core.store.MemoryStoreSettingStorage;
6-
import codemeans.shopify4j.core.store.StoreFactory;
7-
import codemeans.shopify4j.core.store.StoreSetting;
4+
import codemeans.shopify4j.core.base.CachedClientFactory;
5+
import codemeans.shopify4j.core.base.ClientFactory;
6+
import codemeans.shopify4j.core.base.MemoryStoreSettingStorage;
7+
import codemeans.shopify4j.core.base.StoreSetting;
88
import codemeans.shopify4j.graphql.GraphqlInvoker;
99
import codemeans.shopify4j.graphql.OkHttpGraphqlInvoker;
1010
import java.io.File;
@@ -28,14 +28,14 @@ public class ContextForTest {
2828

2929
public static final GraphqlInvoker INVOKER = OkHttpGraphqlInvoker.admin(
3030
new PrivateAppAdminAccessTokenProvider(STORE_SETTING_STORAGE));
31-
public static final StoreFactory<GraphqlAdmin> FACTORY = CachedStoreFactory
31+
public static final ClientFactory<GraphqlAdmin> FACTORY = CachedClientFactory
3232
.of(new GraphqlAdminFactory(INVOKER));
3333
public static final GraphqlAdmin TEST_STORE = FACTORY
34-
.getStore(STORE_SETTING.getMyshopifyDomain());
34+
.getClient(STORE_SETTING.getMyshopifyDomain());
3535

3636
private static StoreSetting loadTestStore() {
3737
File workdir = new File(System.getProperty("user.dir")).getParentFile();
38-
File propertiesFile = new File(workdir, "store.properties");
38+
File propertiesFile = new File(workdir, "test.properties");
3939
try (FileInputStream inputStream = new FileInputStream(propertiesFile)) {
4040
PROPERTIES.load(inputStream);
4141
return StoreSetting.fromProperties(PROPERTIES);

graphql-partner-api/build.gradle

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
dependencies {
2+
// lombok
3+
annotationProcessor("org.projectlombok:lombok:$lombokVersion")
4+
compileOnly("org.projectlombok:lombok:$lombokVersion")
5+
testCompileOnly("org.projectlombok:lombok:$lombokVersion")
6+
7+
api(project(":shopify4j-core"))
8+
api(project(":graphql-partner-schema"))
9+
10+
api("com.squareup.okhttp3:okhttp:$okhttpVersion")
11+
12+
api("commons-io:commons-io:$commonsIOVersion")
13+
14+
// test
15+
testImplementation("junit:junit:$junitVersion")
16+
testImplementation("org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion")
17+
18+
}
19+
20+
description "Java SDK for Shopify Partner GraphQL API"
21+
apply from: "$rootDir/publish.gradle"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package codemeans.shopify4j.graphql.partner;
2+
3+
import codemeans.shopify4j.core.exception.GraphqlApiException;
4+
import codemeans.shopify4j.graphql.GraphqlInvoker;
5+
import codemeans.shopify4j.graphql.partner.exception.GraphqlPartnerQueryException;
6+
import codemeans.shopify4j.graphql.partner.exception.GraphqlPartnerSchemaException;
7+
import codemeans.shopify4j.graphql.partner.types.QueryResponse;
8+
import codemeans.shopify4j.graphql.partner.types.QueryRootQuery;
9+
import com.shopify.graphql.support.SchemaViolationError;
10+
11+
/**
12+
* @author: yuanwq
13+
* @date: 2021-01-26
14+
*/
15+
public class DefaultGraphqlPartner implements GraphqlPartner {
16+
17+
private final String organizationId;
18+
private final String apiVersion;
19+
private final String graphqlEndpoint;
20+
private final GraphqlInvoker invoker;
21+
22+
public DefaultGraphqlPartner(String organizationId, String apiVersion,
23+
GraphqlInvoker invoker) {
24+
this.organizationId = organizationId;
25+
this.apiVersion = apiVersion;
26+
this.graphqlEndpoint = String.format("https://partners.shopify.com/%s/api/%s/graphql.json",
27+
this.organizationId, apiVersion);
28+
this.invoker = invoker;
29+
}
30+
31+
@Override
32+
public String getOrganizationId() {
33+
return organizationId;
34+
}
35+
36+
@Override
37+
public String getApiVersion() {
38+
return apiVersion;
39+
}
40+
41+
@Override
42+
public String getGraphqlEndpoint() {
43+
return graphqlEndpoint;
44+
}
45+
46+
@Override
47+
public String request(String query) throws GraphqlApiException {
48+
return invoker.request(graphqlEndpoint, query);
49+
}
50+
51+
@Override
52+
public QueryResponse query(QueryRootQuery query) throws GraphqlApiException {
53+
String resp = null;
54+
try {
55+
String queryBody = query.toString();
56+
resp = invoker.request(graphqlEndpoint, queryBody);
57+
QueryResponse response = QueryResponse.fromJson(resp);
58+
if (response.getErrors() != null && !response.getErrors().isEmpty()) {
59+
throw new GraphqlPartnerQueryException(query, response);
60+
}
61+
return response;
62+
} catch (SchemaViolationError schemaViolationError) {
63+
throw new GraphqlPartnerSchemaException(query, resp, schemaViolationError);
64+
}
65+
}
66+
67+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package codemeans.shopify4j.graphql.partner;
2+
3+
import codemeans.shopify4j.core.exception.GraphqlApiException;
4+
import codemeans.shopify4j.graphql.partner.types.QueryResponse;
5+
import codemeans.shopify4j.graphql.partner.types.QueryRootQuery;
6+
7+
/**
8+
* @author: yuanwq
9+
* @date: 2021-01-26
10+
*/
11+
public interface GraphqlPartner {
12+
13+
String getOrganizationId();
14+
15+
String getApiVersion();
16+
17+
String getGraphqlEndpoint();
18+
19+
/**
20+
* 原始请求
21+
*/
22+
String request(String query) throws GraphqlApiException;
23+
24+
QueryResponse query(QueryRootQuery query) throws GraphqlApiException;
25+
26+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package codemeans.shopify4j.graphql.partner;
2+
3+
import codemeans.shopify4j.core.base.CachedClientFactory;
4+
import codemeans.shopify4j.core.base.ClientFactory;
5+
import codemeans.shopify4j.graphql.GraphqlInvoker;
6+
import lombok.Data;
7+
import lombok.NonNull;
8+
9+
/**
10+
* @author: yuanwq
11+
* @date: 2021-01-12
12+
*/
13+
@Data
14+
public class GraphqlPartnerFactory implements ClientFactory<GraphqlPartner> {
15+
16+
private final GraphqlInvoker graphqlInvoker;
17+
private String apiVersion = "2021-04";
18+
19+
public GraphqlPartnerFactory(@NonNull GraphqlInvoker graphqlInvoker) {
20+
this.graphqlInvoker = graphqlInvoker;
21+
}
22+
23+
@Override
24+
public GraphqlPartner getClient(String organizationId) {
25+
return new DefaultGraphqlPartner(organizationId, apiVersion, graphqlInvoker);
26+
}
27+
28+
public CachedGraphqlPartnerFactory cached() {
29+
return new CachedGraphqlPartnerFactory(this);
30+
}
31+
32+
public static class CachedGraphqlPartnerFactory extends CachedClientFactory<GraphqlPartner> {
33+
34+
protected CachedGraphqlPartnerFactory(ClientFactory delegate) {
35+
super(delegate);
36+
}
37+
}
38+
39+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package codemeans.shopify4j.graphql.partner.exception;
2+
3+
import codemeans.shopify4j.core.exception.GraphqlApiException;
4+
import codemeans.shopify4j.graphql.partner.types.QueryResponse;
5+
import codemeans.shopify4j.graphql.partner.types.QueryRootQuery;
6+
import com.shopify.graphql.support.Error;
7+
import java.util.Collections;
8+
import java.util.List;
9+
import lombok.Getter;
10+
11+
/**
12+
* @author: yuanwq
13+
* @date: 2021-01-26
14+
*/
15+
public class GraphqlPartnerQueryException extends GraphqlApiException {
16+
17+
@Getter
18+
private QueryRootQuery query;
19+
@Getter
20+
private QueryResponse response;
21+
@Getter
22+
private List<Error> errors;
23+
24+
public GraphqlPartnerQueryException(QueryRootQuery query, QueryResponse response) {
25+
super("Query: " + query + ", Response: " + response.toJson());
26+
this.query = query;
27+
this.response = response;
28+
this.errors = response.getErrors() != null ? response.getErrors() : Collections.emptyList();
29+
}
30+
}

0 commit comments

Comments
 (0)