Test APIs in Your Local Environment Before integrating third-party APIs in your web application, it’s better to test the APIs with an API tool like Postman to ensure the APIs work properly in your local environment. It can also let you get familiar with the APIs.
Add API Configurations to Your Project There are some common configurations of third-party APIs you need to add to your project. For example, authorization information (appId, appSecret), API URL prefix, and so on.
Add Configurations Add the configurations to your spring boot configuration file application.yaml
:
thirdParty: thirdParty1: appId: appSecret: apiBaseUrl: thirdParty2: ...
Define the Configuration Bean Add a spring bean to receive the configurations:
YourThirdPartyConfig.java
@Configuration @EnableConfigurationProperties @ConfigurationProperties(prefix = "thirdParty.yourThirdPartyName") @Data public class YourThirdPartyConfig { protected String appId; protected String appSecret; protected String apiBaseUrl; }
You can access the configurations by @Autowired
it
@Autowired private YourThirdPartyConfig yourThirdPartyConfig;
String appId = yourThirdPartyConfig.appId;String appSecret = yourThirdPartyConfig.appSecret;String apiBaseUrl = yourThirdPartyConfig.apiBaseUrl;
Define Response Code public class YourThirdPartyErrorCode { public static final Integer SUCCESS = 0 ; public static final Integer INVALID_APPID = 1 ; public static final Integer INVALID_TOKEN = 2 ; }
Define API URLs public class YourThirdPartyApiUrl { public static class Module1 { public static final String xxx_URL = "" ; } public static class Module2 { public static final String xxx_URL = "" ; } }
Define Base Service @RequiredArgsConstructor public abstract class YourThirdPartyBaseService { protected final YourThirdPartyConfig yourThirdPartyConfig; private final RestTemplate restTemplate; public ObjectNode getRequest (String url, MultiValueMap params) throws IOException { UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl( yourThirdPartyConfig.apiBaseUrl + url) .queryParams(params); ResponseEntity<String> response = restTemplate.getForEntity(uriBuilder.toUriString(), String.class); if (response.getStatusCode().is2xxSuccessful()) { ObjectNode jsonObject = JacksonJsonUtil.jsonStrToJsonObject(response.getBody()); if (YourThirdPartyErrorCode.SUCCESS.equals(jsonObject.get("code" ).asInt())) { return jsonObject; } else { throw new RuntimeException ("Failed to get access token: " + jsonObject.get("message" ).asText()); } } else { throw new RuntimeException ("Failed to get access token: HTTP error code " + response.getStatusCodeValue()); } } }
Get and Cache Access Token @Service @Slf4j @RequiredArgsConstructor public class YourThirdPartyTokenService extends YourThirdPartyBaseService { public static final String KEY_ACCESS_TOKEN = "yourThirdParty:%s:access_token" ; private final YourThirdPartyConfig yourThirdPartyConfig; private final RestTemplate restTemplate; private final RedisUtil redisUtil; public String getAccessToken () throws IOException { return getAccessToken(yourThirdPartyConfig.appId, yourThirdPartyConfig.appSecret); } public String getAccessToken (String appId, String appSecret) throws IOException { String accessToken = getAccessTokenFromCache(appId); if (StringUtils.isNotBlank(accessToken)) { log.debug("get access_token from redis: {}" , accessToken); return accessToken; } log.debug("get access_token from API" ); ObjectNode jsonObject = getTokenInfoFromApi(appId, appSecret); setTokenToCache(jsonObject, appId); return jsonObject.get("accessToken" ).asText(); } private String getAccessTokenFromCache (String appId) { return redisUtil.get(String.format(KEY_ACCESS_TOKEN, appId), 0 ); } private void setTokenToCache (ObjectNode jsonObject, String appId) { String accessToken = jsonObject.get("result" ).get("accessToken" ).asText(); Integer expiresIn = jsonObject.get("result" ).get("expires" ).asInt(); redisUtil.set(String.format(KEY_ACCESS_TOKEN, appId), accessToken, 0 , "nx" , "ex" , expiresIn - 60 ); } public ObjectNode getTokenInfoFromApi (String appId, String appSecret) throws IOException { MultiValueMap<String, String> params = new LinkedMultiValueMap <>(); params.put("appId" , Arrays.asList(apiKey)); params.put("appSecret" , Arrays.asList(secretKey)); return super .getRequest(YourThirdPartyApiUrl.Token.GET_ACCESS_TOKEN_URL, params); } }
Write Code Define the API Interfaces Here we use the example of the social login API service to demonstrate.
public interface SocialLoginService { JSONObject func1 (JSONObject params) ; JSONObject func1 (JSONObject params) ; }
Why use JSONObject as parameters and return types of methods of the interface?
Different third-party API service platforms have different data structures. The parameters and return types of methods need to be extensible.
Define Constants Keys for API parameters
public class Auth0Key { public static final String CODE = "code" ; public static final String MSG = "msg" ; public static final String USER_NAME = "user_name" ; }
API request URIs
public class Auth0Url { public static final String LOGIN = "/login" ; public static final String GET_USER_INFO = "/user/getInfo" ; }
Write the API Implementing Class @Service public class Auth0SocialLoginService implements SocialLoginService { @Autowired private Auth0Config auth0Config; public JSONObject func1 (JSONObject params) { ... } public JSONObject func2 (JSONObject params) { ... } }
Common third-party APIs and their class names
API Service
Interface Name
Implementation Name
Cloud Object Storage
COSService
AwsCOSService AzureCOSService
Push Notification APIs
PushNotificationService
OneSignalPushService
Social Media Login APIs
SocialLoginService
Auth0SocialLoginService FirebaseSocialLoginService
Write Parameter Builders and Result Handlers Parameter builders
public interface SocialLoginParamBuilder { JSONObject getFunc1Param (Xxx entity) ; JSONObject getFunc2Param (Xxx entity) ; }
@Component public class Auth0SocialLoginParamBuilder { JSONObject getFunc1Param (Xxx entity) {...} JSONObject getFunc2Param (Xxx entity) {...} }
Result handlers
public interface SocialLoginResultHandler { Vo handleFunc1Result (JSONObject result) ; Vo handleFunc2Result (JSONObject result) ; }
@Component public class Auth0SocialLoginResultHandler { Vo handleFunc1Result (JSONObject result) {...} Vo handleFunc2Result (JSONObject result) {...} }
Use Your Interface @Autowired @Qualifier("auth0SocialLoginService") private SocialLoginService socialLoginService;@Autowired private SocialLoginService auth0SocialLoginService; @Autowired @Qualifier("auth0SocialLoginParamBuilder") private SocialLoginParamBuilder socialLoginParamBuilder;@Autowired @Qualifier("auth0SocialLoginResultHandler") private SocialLoginResultHandler socialLoginResultHandler;
JSONObject params = auth0SocialLoginParamBuilder.getFunc1Param(entity);JSONObject result = auth0SocialLoginService.func1(params);Vo vo = auth0SocialLoginResultHandler.handleFunc1Result(result);