天天看點

發現一個新的shopify的Java SDK開源項目,使用Docker編譯、運作

作者:freewebsys

#头条创作挑战赛#

目录

  • 前言
  • 1,关于shopify java调研
  • 2,找到一个shopify的JavaSDK最新项目
  • 3,使用OAuth2 进行授权的逻辑
  • 4,解决相关问题,解决配置依赖问题,项目启动成功
  • 5,项目总结

1,关于shopify java调研

Shopify 是由Tobi Lütke 创办的加拿大电子商务软件开发商,总部位于加拿大首都渥太华。 Shopify 是一站式SaaS模式的电商服务平台,为电商卖家提供搭建网店的技术和模版,管理全渠道的营销、售卖、支付、物流等服务。 2015 年Shopify 在纽约与多伦多两地证券交易所上市。

要是做出海项目,shopif还是绕不开的。找到相关的开发文档:

https://shopify.dev/apps/auth

发现没有java 的tools。

發現一個新的shopify的Java SDK開源項目,使用Docker編譯、運作

ruby,python,node,php都是有的,但是没有java的相关代码。

同时从 github上面找也都是 2 年前的老项目,感觉接口会有不兼容的问题。

https://github.com/search?l=Java&q=shopify&type=Repositories

官网上也有问这个问题的:

https://community.shopify.com/c/shopify-apis-and-sdks/java-api-shopify4j-question/m-p/101566

發現一個新的shopify的Java SDK開源項目,使用Docker編譯、運作

2,找到一个shopify的JavaSDK最新项目,2022年6月份的发布的热乎着呢!

偶然的时候发现一篇文章:

https://www.justblackmagic.com/2022/06/10/spring-boot-shopify-app-framework/

發現一個新的shopify的Java SDK開源項目,使用Docker編譯、運作

很低调的,完成了开源项目的 OAuth2 接口,GDPR 请求,GraphQL 等接口。

而且项目非常的新,是 2022年6月份的。

https://github.com/devondragon/SpringShopifyAppFramework

3,使用OAuth2 进行授权的逻辑

使用 shopify 进行 oauth2 的校验逻辑如下:

發現一個新的shopify的Java SDK開源項目,使用Docker編譯、運作

4,使用Docker解决相关编译问题,解决配置问题,项目启动成功

目前看这个开源项目还不错,可以进行相关的使用和研究下。

但是目前依赖还有点问题,一点点地在进行排查解决。

项目是使用gradle进行编译,jd17 ,和本地电脑的环境不一样,直接上 docker,简单粗暴。

gradle:jdk17

同时项目还依赖 mariadb 10数据库,也使用docker一起创建。并映射端口3306。

配置docker的国内站点,加速下载。

/etc/docker/daemon.json 
{
  "data-root": "/data/docker",
  "registry-mirrors" : [
      "https://registry.docker-cn.com"
    ]
}
           

精简gradle 代码,不构建 nodejs 的项目,且配置好国内的gradle 镜像,加速下载依赖包。

plugins {
	id 'org.springframework.boot' version '2.7.3'
	id 'io.spring.dependency-management' version '1.0.13.RELEASE'
	id 'java'
	id "com.github.ben-manes.versions" version "0.42.0"
}

group = 'com.justblackmagic'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
targetCompatibility = '17'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
	dev
}

repositories {
	mavenCentral()
		maven { name "Alibaba" ; url "https://maven.aliyun.com/repository/public" }
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-actuator'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-jersey'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
	implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
	implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
	implementation 'org.springframework.boot:spring-boot-starter-webflux'
	implementation 'joda-time:joda-time:2.11.1'
	implementation 'org.apache.commons:commons-lang3:3.12.0'
	implementation 'org.apache.commons:commons-text:1.9'
	implementation 'com.github.rholder:guava-retrying:2.0.0'
	implementation 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.13.3'
	implementation 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.13.3'
	implementation 'commons-io:commons-io:2.11.0'
 	implementation 'io.netty:netty-resolver-dns-native-macos:4.1.80.Final:osx-aarch_64' 

    implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
	runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'

	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	// runtimeOnly 'io.micrometer:micrometer-registry-new-relic'
	annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
	testImplementation 'com.h2database:h2'
	testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
	implementation 'com.github.rest-driver:rest-driver:2.0.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
}

bootJar {
    launchScript{
        properties 'confFolder': '/opt/app/conf/'
    }
}

bootRun {
    // Use Spring Boot DevTool only when we run Gradle bootRun task
    classpath = sourceSets.main.runtimeClasspath + configurations.dev
    
    if (project.hasProperty('profiles')) {
		environment SPRING_PROFILES_ACTIVE: profiles
	} else {
		def profiles = 'local'
		environment SPRING_PROFILES_ACTIVE: profiles
	}
}
           

mysql的设置默认密码是root,然后修改 application.yaml 的mysql 配置文件:

要是使用 mysql 的话,需要自己创建数据库:

项目使用的是mariadb 驱动,所以url也要修改下。

CREATE DATABASE `shopifytest` CHARACTER SET utf8 COLLATE utf8_general_ci;

# application.yaml 中的配置
...
spring:
  application:
    name: Shopify Integration Framework
  datasource:
    driverClassName: org.mariadb.jdbc.Driver
    password: root
    url: jdbc:mariadb://mariadb:3306/shopifytest?createDatabaseIfNotExist=true
    username: root
...
           

少一个 shopify 的配置文件:application.properties ,放到和 application.yaml 目录一样的地方,有些配置缺少,但是需要去shopify 上去申请 apiKey,apiSecrt。

同时要有个外网的域名,或者使用 ngrok 进行内网穿透,做开发。

# spring mvc datetime format
# https://www.baeldung.com/spring-boot-formatting-json-dates
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

# 配置 shopify 配置店铺信息。
SHOPIFY_APP_HOSTNAME=demo
shopify.auth.apiKey=123456
shopify.auth.apiSecret=123456
baseUrl=demo
registrationId=us
shopify.test.storeName=testStoreName

# 新增加配置。
shopify.api.graphql.version=2021-10
shopify.api.rest.version=2021-10
           

执行命令:

# 下载代码
git clone https://github.com/devondragon/SpringShopifyAppFramework.git

# 创建个 mysql 的数据库。依赖这个,mariadb 支持自动创建数据库参数。
docker run -itd --name mariadb -p 3306:3306 -e MARIADB_ROOT_PASSWORD=root mariadb:10
# 使用镜像运行程序:
docker run -itd --name shopify --link mariadb -p 9090:8080 -v `pwd`/SpringShopifyAppFramework:/home/gradle gradle:jdk17 sleep 9999999d

# 然后开始进行项目的构建:
$ gradle build
Starting a Gradle Daemon (subsequent builds will be faster)

> Task :compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

BUILD SUCCESSFUL in 8m 30s 使用国内镜像下载速度快很多。)
7 actionable tasks: 7 executed

           

然后在启动:

# gradle bootRun

> Task :bootRun
07:46:16.607 [Thread-0] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@6026363f

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.3)
...
org.springframework.security.web.session.SessionManagementFilter@6f76ea99, org.springframework.security.web.access.ExceptionTranslationFilter@500646fd, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@3490f9e2]
2022-10-29 07:46:20.535  INFO 559 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2022-10-29 07:46:20.538  INFO 559 --- [  restartedMain] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 1 endpoint(s) beneath base path '/actuator'
2022-10-29 07:46:20.569  INFO 559 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2022-10-29 07:46:20.583  INFO 559 --- [  restartedMain] c.j.s.e.listener.InstallTestListener     : Context Refreshed Event
2022-10-29 07:46:20.679  INFO 559 --- [  restartedMain] c.j.s.e.listener.InstallTestListener     : No Test Store Oauth Client found. Will not run API tests.
2022-10-29 07:46:20.681  INFO 559 --- [  restartedMain] c.j.shopify.ShopifyApplication           : Started ShopifyApplication in 4.068 seconds (JVM running for 4.394)
<==========---> 80% EXECUTING [2m 58s]

           

问题都已经解决启动成功,可以启动成功了。

剩下的就得有真实的域名地址,和门店信息配置啥的了可以。

同时创建了两个数据库表:

CREATE TABLE `authorized_client` (
  `client_registration_id` varchar(255) NOT NULL,
  `principal_name` varchar(255) NOT NULL,
  `access_token_expires_at` datetime(6) DEFAULT NULL,
  `access_token_issued_at` datetime(6) DEFAULT NULL,
  `access_token_type` varchar(255) DEFAULT NULL,
  `access_token_value` varchar(255) DEFAULT NULL,
  `created_at` datetime(6) DEFAULT NULL,
  PRIMARY KEY (`client_registration_id`,`principal_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `authorized_client_access_token_scopes` (
  `authorized_client_client_registration_id` varchar(255) NOT NULL,
  `authorized_client_principal_name` varchar(255) NOT NULL,
  `access_token_scopes` varchar(255) DEFAULT NULL,
  KEY `FKan7pq8uul8sjqdqmmofkux27d` (`authorized_client_client_registration_id`,`authorized_client_principal_name`),
  CONSTRAINT `FKan7pq8uul8sjqdqmmofkux27d` 
  FOREIGN KEY (`authorized_client_client_registration_id`, `authorized_client_principal_name`) 
REFERENCES `authorized_client` (`client_registration_id`, `principal_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

           

5,项目总结

java 项目中包括很多的接口,都已经实现了。包括 OAuth2登录授权,graphql,rest接口,还有监听等等。

非常丰富,而且也是比较新的项目非常值得学习研究。

技术栈是spring boot的,使用 jpa hibernate 做存储,保存author信息。

项目成功跑通,但是具体咋使继续研究。