0
# Cloud Development
1
2
WeChat Cloud Development integration including cloud functions, database operations, cloud storage management, and serverless backend services for WeChat MiniApp applications.
3
4
## Capabilities
5
6
### Cloud Service Interface
7
8
Core cloud development operations for serverless backend functionality.
9
10
```java { .api }
11
public interface WxMaCloudService {
12
// Cloud Function Operations
13
WxCloudInvokeResult invokeCloudFunction(String env, String functionName, String data) throws WxErrorException;
14
WxCloudInvokeResult invokeCloudFunction(WxCloudInvokeRequest request) throws WxErrorException;
15
16
// Database Operations
17
WxCloudDatabaseResult databaseQuery(String env, String query) throws WxErrorException;
18
WxCloudDatabaseResult databaseAdd(String env, String collection, String data) throws WxErrorException;
19
WxCloudDatabaseResult databaseUpdate(String env, String collection, String query, String data) throws WxErrorException;
20
WxCloudDatabaseResult databaseDelete(String env, String collection, String query) throws WxErrorException;
21
WxCloudDatabaseResult databaseAggregate(String env, String collection, String pipeline) throws WxErrorException;
22
WxCloudDatabaseResult databaseCount(String env, String collection, String query) throws WxErrorException;
23
24
// File Operations
25
WxCloudUploadFileResult uploadFile(String env, String path, InputStream inputStream) throws WxErrorException;
26
WxCloudUploadFileResult uploadFile(WxCloudUploadFileRequest request) throws WxErrorException;
27
WxCloudDownloadFileResult downloadFile(String env, String fileList) throws WxErrorException;
28
WxCloudDeleteFileResult deleteFile(String env, List<String> fileIds) throws WxErrorException;
29
30
// Storage Operations
31
WxCloudGetTempFileUrlResult getTempFileUrl(String env, List<String> fileList) throws WxErrorException;
32
WxCloudBatchDownloadFileResult batchDownloadFile(String env, List<String> fileList, Long zipName) throws WxErrorException;
33
}
34
```
35
36
### Cloud Function Models
37
38
Data models for cloud function invocation and management.
39
40
```java { .api }
41
public class WxCloudInvokeRequest implements Serializable {
42
private String env; // Cloud environment ID
43
private String functionName; // Function name
44
private String requestData; // Function input data (JSON string)
45
46
public WxCloudInvokeRequest();
47
public WxCloudInvokeRequest(String env, String functionName, String requestData);
48
49
// Getters and setters
50
public String getEnv();
51
public void setEnv(String env);
52
public String getFunctionName();
53
public void setFunctionName(String functionName);
54
public String getRequestData();
55
public void setRequestData(String requestData);
56
57
// Convenience methods
58
public WxCloudInvokeRequest withData(Object data);
59
public String toJson();
60
}
61
62
public class WxCloudInvokeResult implements Serializable {
63
private Integer errCode; // Error code (0: success)
64
private String errMsg; // Error message
65
private String requestId; // Request ID for tracking
66
private String respData; // Function response data
67
68
// Getters and setters
69
public Integer getErrCode();
70
public void setErrCode(Integer errCode);
71
public String getErrMsg();
72
public void setErrMsg(String errMsg);
73
public String getRequestId();
74
public void setRequestId(String requestId);
75
public String getRespData();
76
public void setRespData(String respData);
77
78
// Convenience methods
79
public boolean isSuccess();
80
public <T> T getResponseData(Class<T> clazz);
81
public JsonObject getResponseAsJson();
82
}
83
```
84
85
### Cloud Database Models
86
87
Data models for database operations and queries.
88
89
```java { .api }
90
public class WxCloudDatabaseRequest implements Serializable {
91
private String env; // Cloud environment ID
92
private String collection; // Collection name
93
private String query; // Query conditions (JSON string)
94
private String data; // Data to insert/update (JSON string)
95
private String pipeline; // Aggregation pipeline (JSON string)
96
private Integer limit; // Query limit
97
private Integer offset; // Query offset
98
99
// Getters and setters
100
public String getEnv();
101
public void setEnv(String env);
102
public String getCollection();
103
public void setCollection(String collection);
104
public String getQuery();
105
public void setQuery(String query);
106
public String getData();
107
public void setData(String data);
108
109
// Builder methods
110
public WxCloudDatabaseRequest withQuery(Object queryObj);
111
public WxCloudDatabaseRequest withData(Object dataObj);
112
public WxCloudDatabaseRequest withLimit(int limit);
113
public WxCloudDatabaseRequest withOffset(int offset);
114
}
115
116
public class WxCloudDatabaseResult implements Serializable {
117
private Integer errCode; // Error code
118
private String errMsg; // Error message
119
private List<JsonObject> data; // Query results
120
private Integer pager; // Pagination info
121
private Integer matched; // Matched documents count
122
private Integer modified; // Modified documents count
123
private Integer deleted; // Deleted documents count
124
private String id; // Inserted document ID
125
126
// Getters and setters
127
public Integer getErrCode();
128
public void setErrCode(Integer errCode);
129
public List<JsonObject> getData();
130
public void setData(List<JsonObject> data);
131
public Integer getMatched();
132
public void setMatched(Integer matched);
133
134
// Convenience methods
135
public boolean isSuccess();
136
public <T> List<T> getDataAs(Class<T> clazz);
137
public <T> T getFirstData(Class<T> clazz);
138
}
139
```
140
141
### Cloud Storage Models
142
143
Data models for file upload, download, and storage operations.
144
145
```java { .api }
146
public class WxCloudUploadFileRequest implements Serializable {
147
private String env; // Cloud environment ID
148
private String path; // File path in cloud storage
149
private InputStream inputStream; // File input stream
150
private String fileName; // Original file name
151
152
public WxCloudUploadFileRequest();
153
public WxCloudUploadFileRequest(String env, String path, InputStream inputStream);
154
155
// Getters and setters
156
public String getEnv();
157
public void setEnv(String env);
158
public String getPath();
159
public void setPath(String path);
160
public InputStream getInputStream();
161
public void setInputStream(InputStream inputStream);
162
}
163
164
public class WxCloudUploadFileResult implements Serializable {
165
private Integer errCode; // Error code
166
private String errMsg; // Error message
167
private String fileId; // Uploaded file ID
168
private String downloadUrl; // Download URL
169
170
// Getters and setters
171
public Integer getErrCode();
172
public void setErrCode(Integer errCode);
173
public String getFileId();
174
public void setFileId(String fileId);
175
public String getDownloadUrl();
176
public void setDownloadUrl(String downloadUrl);
177
178
public boolean isSuccess();
179
}
180
181
public class WxCloudDownloadFileResult implements Serializable {
182
private Integer errCode; // Error code
183
private String errMsg; // Error message
184
private List<FileInfo> fileList; // Downloaded file information
185
186
public static class FileInfo {
187
private String fileId; // File ID
188
private String downloadUrl; // Temporary download URL
189
private Integer status; // Download status
190
191
public String getFileId();
192
public void setFileId(String fileId);
193
public String getDownloadUrl();
194
public void setDownloadUrl(String downloadUrl);
195
public Integer getStatus();
196
public void setStatus(Integer status);
197
}
198
199
// Getters and setters
200
public List<FileInfo> getFileList();
201
public void setFileList(List<FileInfo> fileList);
202
public boolean isSuccess();
203
}
204
```
205
206
## Usage Examples
207
208
### Cloud Function Integration
209
210
#### Invoke Cloud Functions
211
212
```java
213
@Service
214
public class CloudFunctionService {
215
216
@Autowired
217
private WxMaService wxMaService;
218
219
@Value("${wechat.cloud.env}")
220
private String cloudEnv;
221
222
public <T> T invokeFunction(String functionName, Object requestData, Class<T> responseType) {
223
try {
224
String jsonData = JsonUtils.toJson(requestData);
225
226
WxCloudInvokeResult result = wxMaService.getCloudService()
227
.invokeCloudFunction(cloudEnv, functionName, jsonData);
228
229
if (result.isSuccess()) {
230
return result.getResponseData(responseType);
231
} else {
232
throw new CloudFunctionException(
233
"Function invocation failed: " + result.getErrMsg());
234
}
235
236
} catch (WxErrorException e) {
237
logger.error("Cloud function {} invocation failed: {}", functionName, e.getMessage());
238
throw new CloudFunctionException("Failed to invoke cloud function", e);
239
}
240
}
241
242
public UserProfileResult getUserProfile(String userId) {
243
Map<String, Object> params = new HashMap<>();
244
params.put("userId", userId);
245
params.put("includePrivateData", false);
246
247
return invokeFunction("getUserProfile", params, UserProfileResult.class);
248
}
249
250
public PaymentResult processPayment(PaymentRequest paymentRequest) {
251
try {
252
WxCloudInvokeRequest request = new WxCloudInvokeRequest()
253
.setEnv(cloudEnv)
254
.setFunctionName("processPayment")
255
.withData(paymentRequest);
256
257
WxCloudInvokeResult result = wxMaService.getCloudService()
258
.invokeCloudFunction(request);
259
260
if (result.isSuccess()) {
261
return result.getResponseData(PaymentResult.class);
262
} else {
263
logger.error("Payment processing failed: {}", result.getErrMsg());
264
throw new PaymentProcessingException(result.getErrMsg());
265
}
266
267
} catch (WxErrorException e) {
268
logger.error("Payment cloud function failed: {}", e.getMessage());
269
throw new PaymentProcessingException("Payment processing error", e);
270
}
271
}
272
273
@Async
274
public CompletableFuture<Void> sendAsyncNotification(NotificationRequest notification) {
275
return CompletableFuture.runAsync(() -> {
276
try {
277
invokeFunction("sendNotification", notification, Void.class);
278
logger.info("Async notification sent for user: {}", notification.getUserId());
279
280
} catch (Exception e) {
281
logger.error("Async notification failed: {}", e.getMessage());
282
}
283
});
284
}
285
}
286
```
287
288
### Cloud Database Operations
289
290
#### Database CRUD Operations
291
292
```java
293
@Service
294
public class CloudDatabaseService {
295
296
@Autowired
297
private WxMaService wxMaService;
298
299
@Value("${wechat.cloud.env}")
300
private String cloudEnv;
301
302
public <T> List<T> findDocuments(String collection, Object query, Class<T> entityType) {
303
try {
304
String queryJson = JsonUtils.toJson(query);
305
306
WxCloudDatabaseResult result = wxMaService.getCloudService()
307
.databaseQuery(cloudEnv, queryJson);
308
309
if (result.isSuccess()) {
310
return result.getDataAs(entityType);
311
} else {
312
throw new CloudDatabaseException("Query failed: " + result.getErrMsg());
313
}
314
315
} catch (WxErrorException e) {
316
logger.error("Database query failed for collection {}: {}", collection, e.getMessage());
317
throw new CloudDatabaseException("Database query failed", e);
318
}
319
}
320
321
public String createDocument(String collection, Object document) {
322
try {
323
String documentJson = JsonUtils.toJson(document);
324
325
WxCloudDatabaseResult result = wxMaService.getCloudService()
326
.databaseAdd(cloudEnv, collection, documentJson);
327
328
if (result.isSuccess()) {
329
return result.getId();
330
} else {
331
throw new CloudDatabaseException("Insert failed: " + result.getErrMsg());
332
}
333
334
} catch (WxErrorException e) {
335
logger.error("Document creation failed for collection {}: {}", collection, e.getMessage());
336
throw new CloudDatabaseException("Document creation failed", e);
337
}
338
}
339
340
public int updateDocuments(String collection, Object query, Object updateData) {
341
try {
342
String queryJson = JsonUtils.toJson(query);
343
String updateJson = JsonUtils.toJson(updateData);
344
345
WxCloudDatabaseResult result = wxMaService.getCloudService()
346
.databaseUpdate(cloudEnv, collection, queryJson, updateJson);
347
348
if (result.isSuccess()) {
349
return result.getModified();
350
} else {
351
throw new CloudDatabaseException("Update failed: " + result.getErrMsg());
352
}
353
354
} catch (WxErrorException e) {
355
logger.error("Document update failed for collection {}: {}", collection, e.getMessage());
356
throw new CloudDatabaseException("Document update failed", e);
357
}
358
}
359
360
public int deleteDocuments(String collection, Object query) {
361
try {
362
String queryJson = JsonUtils.toJson(query);
363
364
WxCloudDatabaseResult result = wxMaService.getCloudService()
365
.databaseDelete(cloudEnv, collection, queryJson);
366
367
if (result.isSuccess()) {
368
return result.getDeleted();
369
} else {
370
throw new CloudDatabaseException("Delete failed: " + result.getErrMsg());
371
}
372
373
} catch (WxErrorException e) {
374
logger.error("Document deletion failed for collection {}: {}", collection, e.getMessage());
375
throw new CloudDatabaseException("Document deletion failed", e);
376
}
377
}
378
}
379
```
380
381
#### Advanced Database Operations
382
383
```java
384
@Repository
385
public class UserCloudRepository {
386
387
@Autowired
388
private CloudDatabaseService cloudDb;
389
390
private static final String USER_COLLECTION = "users";
391
392
public Optional<User> findByOpenid(String openid) {
393
Map<String, Object> query = Map.of("openid", openid);
394
395
List<User> users = cloudDb.findDocuments(USER_COLLECTION, query, User.class);
396
return users.isEmpty() ? Optional.empty() : Optional.of(users.get(0));
397
}
398
399
public List<User> findActiveUsers() {
400
Map<String, Object> query = Map.of(
401
"status", "active",
402
"lastLoginTime", Map.of(
403
"$gte", System.currentTimeMillis() - (30L * 24 * 60 * 60 * 1000) // 30 days
404
)
405
);
406
407
return cloudDb.findDocuments(USER_COLLECTION, query, User.class);
408
}
409
410
public String saveUser(User user) {
411
user.setCreatedTime(System.currentTimeMillis());
412
user.setUpdatedTime(System.currentTimeMillis());
413
414
return cloudDb.createDocument(USER_COLLECTION, user);
415
}
416
417
public void updateUserLastLogin(String openid) {
418
Map<String, Object> query = Map.of("openid", openid);
419
Map<String, Object> update = Map.of(
420
"lastLoginTime", System.currentTimeMillis(),
421
"updatedTime", System.currentTimeMillis()
422
);
423
424
cloudDb.updateDocuments(USER_COLLECTION, query, update);
425
}
426
427
public long countUsersByCity(String city) {
428
try {
429
Map<String, Object> query = Map.of("city", city);
430
String queryJson = JsonUtils.toJson(query);
431
432
WxCloudDatabaseResult result = wxMaService.getCloudService()
433
.databaseCount(cloudEnv, USER_COLLECTION, queryJson);
434
435
if (result.isSuccess()) {
436
return result.getMatched();
437
}
438
439
} catch (WxErrorException e) {
440
logger.error("User count query failed: {}", e.getMessage());
441
}
442
443
return 0;
444
}
445
446
public List<UserAggregateResult> aggregateUsersByRegion() {
447
try {
448
List<Map<String, Object>> pipeline = Arrays.asList(
449
Map.of("$group", Map.of(
450
"_id", "$province",
451
"count", Map.of("$sum", 1),
452
"avgAge", Map.of("$avg", "$age")
453
)),
454
Map.of("$sort", Map.of("count", -1))
455
);
456
457
String pipelineJson = JsonUtils.toJson(pipeline);
458
459
WxCloudDatabaseResult result = wxMaService.getCloudService()
460
.databaseAggregate(cloudEnv, USER_COLLECTION, pipelineJson);
461
462
if (result.isSuccess()) {
463
return result.getDataAs(UserAggregateResult.class);
464
}
465
466
} catch (WxErrorException e) {
467
logger.error("User aggregation failed: {}", e.getMessage());
468
}
469
470
return Collections.emptyList();
471
}
472
}
473
```
474
475
### Cloud Storage Operations
476
477
#### File Upload and Management
478
479
```java
480
@Service
481
public class CloudStorageService {
482
483
@Autowired
484
private WxMaService wxMaService;
485
486
@Value("${wechat.cloud.env}")
487
private String cloudEnv;
488
489
public String uploadFile(MultipartFile file, String folder) {
490
try {
491
// Generate unique file path
492
String fileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
493
String filePath = folder + "/" + fileName;
494
495
WxCloudUploadFileRequest request = new WxCloudUploadFileRequest(
496
cloudEnv, filePath, file.getInputStream()
497
);
498
request.setFileName(file.getOriginalFilename());
499
500
WxCloudUploadFileResult result = wxMaService.getCloudService()
501
.uploadFile(request);
502
503
if (result.isSuccess()) {
504
logger.info("File uploaded to cloud storage: {} -> {}",
505
file.getOriginalFilename(), result.getFileId());
506
return result.getFileId();
507
} else {
508
throw new CloudStorageException("Upload failed: " + result.getErrMsg());
509
}
510
511
} catch (WxErrorException | IOException e) {
512
logger.error("Cloud file upload failed: {}", e.getMessage());
513
throw new CloudStorageException("File upload failed", e);
514
}
515
}
516
517
public String uploadUserAvatar(String openid, MultipartFile avatar) {
518
String avatarFolder = "avatars/" + openid;
519
return uploadFile(avatar, avatarFolder);
520
}
521
522
public String uploadProductImage(String productId, MultipartFile image) {
523
String imageFolder = "products/" + productId;
524
return uploadFile(image, imageFolder);
525
}
526
527
public List<String> getTempDownloadUrls(List<String> fileIds) {
528
try {
529
WxCloudGetTempFileUrlResult result = wxMaService.getCloudService()
530
.getTempFileUrl(cloudEnv, fileIds);
531
532
if (result.isSuccess()) {
533
return result.getFileList().stream()
534
.map(WxCloudGetTempFileUrlResult.FileInfo::getTempFileUrl)
535
.collect(Collectors.toList());
536
} else {
537
throw new CloudStorageException("Get temp URLs failed: " + result.getErrMsg());
538
}
539
540
} catch (WxErrorException e) {
541
logger.error("Get temp file URLs failed: {}", e.getMessage());
542
throw new CloudStorageException("Failed to get temporary URLs", e);
543
}
544
}
545
546
public void deleteFiles(List<String> fileIds) {
547
try {
548
WxCloudDeleteFileResult result = wxMaService.getCloudService()
549
.deleteFile(cloudEnv, fileIds);
550
551
if (result.isSuccess()) {
552
logger.info("Deleted {} files from cloud storage", fileIds.size());
553
} else {
554
logger.warn("Some files failed to delete: {}", result.getErrMsg());
555
}
556
557
} catch (WxErrorException e) {
558
logger.error("File deletion failed: {}", e.getMessage());
559
}
560
}
561
562
@Async
563
public CompletableFuture<String> downloadAndProcessFile(String fileId) {
564
return CompletableFuture.supplyAsync(() -> {
565
try {
566
WxCloudDownloadFileResult result = wxMaService.getCloudService()
567
.downloadFile(cloudEnv, List.of(fileId).toString());
568
569
if (result.isSuccess() && !result.getFileList().isEmpty()) {
570
String downloadUrl = result.getFileList().get(0).getDownloadUrl();
571
572
// Download and process the file
573
byte[] fileContent = downloadFileContent(downloadUrl);
574
575
// Process file content (resize, convert, etc.)
576
byte[] processedContent = processFileContent(fileContent);
577
578
// Upload processed file back to cloud storage
579
String processedFileId = uploadProcessedFile(processedContent);
580
581
return processedFileId;
582
}
583
584
} catch (Exception e) {
585
logger.error("Async file processing failed for {}: {}", fileId, e.getMessage());
586
}
587
588
return null;
589
});
590
}
591
}
592
```
593
594
### Cloud-based User Management
595
596
```java
597
@Service
598
public class CloudUserService {
599
600
@Autowired
601
private CloudFunctionService cloudFunctions;
602
603
@Autowired
604
private CloudDatabaseService cloudDatabase;
605
606
@Autowired
607
private CloudStorageService cloudStorage;
608
609
public UserProfile createUserProfile(UserRegistrationRequest request) {
610
try {
611
// Upload avatar to cloud storage
612
String avatarFileId = null;
613
if (request.getAvatar() != null) {
614
avatarFileId = cloudStorage.uploadUserAvatar(
615
request.getOpenid(), request.getAvatar()
616
);
617
}
618
619
// Create user document in cloud database
620
User user = new User();
621
user.setOpenid(request.getOpenid());
622
user.setNickname(request.getNickname());
623
user.setAvatarFileId(avatarFileId);
624
user.setPhoneNumber(request.getPhoneNumber());
625
user.setStatus("active");
626
627
String userId = cloudDatabase.createDocument("users", user);
628
user.setId(userId);
629
630
// Initialize user data via cloud function
631
Map<String, Object> initParams = Map.of(
632
"userId", userId,
633
"openid", request.getOpenid(),
634
"initialData", request.getInitialData()
635
);
636
637
cloudFunctions.invokeFunction("initializeUser", initParams, Void.class);
638
639
// Build user profile response
640
UserProfile profile = new UserProfile();
641
profile.setUser(user);
642
643
if (avatarFileId != null) {
644
List<String> avatarUrl = cloudStorage.getTempDownloadUrls(List.of(avatarFileId));
645
if (!avatarUrl.isEmpty()) {
646
profile.setAvatarUrl(avatarUrl.get(0));
647
}
648
}
649
650
logger.info("User profile created for: {}", request.getOpenid());
651
return profile;
652
653
} catch (Exception e) {
654
logger.error("User profile creation failed: {}", e.getMessage());
655
throw new UserProfileException("Failed to create user profile", e);
656
}
657
}
658
659
public void updateUserActivity(String openid, UserActivity activity) {
660
// Store activity in cloud database
661
Map<String, Object> activityDoc = Map.of(
662
"openid", openid,
663
"type", activity.getType(),
664
"data", activity.getData(),
665
"timestamp", System.currentTimeMillis()
666
);
667
668
cloudDatabase.createDocument("user_activities", activityDoc);
669
670
// Process activity asynchronously via cloud function
671
Map<String, Object> processParams = Map.of(
672
"openid", openid,
673
"activity", activity
674
);
675
676
cloudFunctions.sendAsyncNotification(new NotificationRequest(
677
"processUserActivity", processParams
678
));
679
}
680
681
public UserAnalytics getUserAnalytics(String openid, Date startDate, Date endDate) {
682
// Use cloud function for complex analytics
683
Map<String, Object> params = Map.of(
684
"openid", openid,
685
"startDate", startDate.getTime(),
686
"endDate", endDate.getTime(),
687
"includeActivities", true,
688
"includePurchases", true
689
);
690
691
return cloudFunctions.invokeFunction("getUserAnalytics", params, UserAnalytics.class);
692
}
693
}
694
```
695
696
### Error Handling and Monitoring
697
698
```java
699
@Component
700
public class CloudServiceMonitor {
701
702
@EventListener
703
public void handleCloudFunctionEvent(CloudFunctionInvokeEvent event) {
704
// Log function invocation metrics
705
logger.info("Cloud function {} invoked with duration: {}ms",
706
event.getFunctionName(), event.getDuration());
707
708
// Alert on function failures
709
if (!event.isSuccess()) {
710
alertService.sendCloudFunctionAlert(event);
711
}
712
713
// Track usage metrics
714
metricsService.recordCloudFunctionUsage(event);
715
}
716
717
@EventListener
718
public void handleDatabaseEvent(CloudDatabaseEvent event) {
719
// Monitor database performance
720
if (event.getDuration() > 5000) { // 5 seconds
721
alertService.sendSlowDatabaseAlert(event);
722
}
723
724
// Track database operations
725
metricsService.recordDatabaseOperation(event);
726
}
727
728
@Scheduled(fixedRate = 300000) // Every 5 minutes
729
public void checkCloudResourceHealth() {
730
try {
731
// Test cloud function connectivity
732
cloudFunctions.invokeFunction("healthCheck", Map.of(), Map.class);
733
734
// Test database connectivity
735
cloudDatabase.findDocuments("health_check", Map.of("type", "ping"), Map.class);
736
737
logger.debug("Cloud resource health check passed");
738
739
} catch (Exception e) {
740
logger.error("Cloud resource health check failed: {}", e.getMessage());
741
alertService.sendCloudHealthAlert(e);
742
}
743
}
744
}
745
```
746
747
This cloud development module provides comprehensive integration with WeChat Cloud Development services, enabling serverless backend functionality with cloud functions, database operations, and cloud storage for WeChat MiniApp applications.