挑戰目標: MockNative Camp前端
今天要來實作更新會員資料API,我的習慣是將request跟response都使用Object class,這樣可以直接做NonNull的檢查以及避免接收到不相關的資料或者是不想要某些欄位被外部更動,像是會員狀態、金幣等等的欄位是不允許被呼叫API更改的。
PatchReq.java 是存放可以被update的欄位,這種用法是我之前在寫Python的習慣,在Python中我會使用marshmallow,更好的是假設有的欄位沒有帶,則會不會出現在dict中,而Java Object宣吿後呼叫時沒有帶的參數會是null如果是boolean則會是false。
我這裡有兩種選擇
通常都是要跟前端溝通,但前端就是我(淚,所以我們使用第二種方式。
PatchReq.java
package com.mock.nativecamp.payload.user;
import lombok.Data;
@Data
public class PatchReq {
private String name;
private String email;
private String password;
private String birthday;
private String gender;
private String credit_token;
private String profilePic;
private boolean news;
private String userNationality;
private String userResidence;
private boolean genderNotify;
private boolean birthdayNotify;
private boolean userNationalityNotify;
private boolean userResidenceNotify;
private String timezone;
}
UsersController.java 新增patch接口
@PatchMapping(path = "/patch/{userId}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public Object patchUser(@PathVariable("userId") String userId, @RequestBody PatchReq patchReq) {
return usersService.updateUser(userId, patchReq);
}
在實作時有發現一個問提,在model中宣告id,在UsersRepository中要新增findById會撞到一定要用
Option<Users> findById(String id);
所以我改變了model的命名,
Users.java
package com.mock.nativecamp.model;
import com.mock.nativecamp.payload.user.PatchReq;
import com.mock.nativecamp.payload.user.SignupReq;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "Users")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
@Id
private String userId;
private String name;
private String email;
private String password;
private String status;
private String coin;
private String timezone;
private String payMethod;
private String nextPayCheck;
private String ssoId;
private String gender;
private String creditToken;
private String profilePic;
private boolean news;
private String birthday;
private String userNationality;
private String userResidence;
private boolean genderNotify;
private boolean birthdayNotify;
private boolean userNationalityNotify;
private boolean userResidenceNotify;
public Users signUser(SignupReq signupReq) {
Users user = new Users();
user.setName(signupReq.getName());
user.setEmail(signupReq.getEmail());
user.setPassword(signupReq.getPassword());
user.setBirthday(signupReq.getBirthday());
user.setGender(signupReq.getGender());
user.setCreditToken(signupReq.getCredit_token());
return user;
}
public Users updateUser(Users user, PatchReq patchReq) {
user.setName(patchReq.getName());
user.setEmail(patchReq.getEmail());
user.setPassword(patchReq.getPassword());
user.setBirthday(patchReq.getBirthday());
user.setGender(patchReq.getGender());
user.setCreditToken(patchReq.getCredit_token());
user.setProfilePic(patchReq.getProfilePic());
user.setNews(patchReq.getNews());
user.setUserNationality(patchReq.getUserNationality());
user.setUserNationalityNotify(patchReq.getUserNationalityNotify());
user.setUserResidence(patchReq.getUserNationality());
user.setUserNationalityNotify(patchReq.getUserNationalityNotify());
user.setGenderNotify(patchReq.getGenderNotify());
user.setBirthdayNotify(patchReq.getBirthdayNotify());
user.setTimezone(patchReq.getTimezone());
return user;
}
}
UsersRepository.java
package com.mock.nativecamp.repository;
import com.mock.nativecamp.model.Users;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UsersRepository extends MongoRepository<Users, String> {
Users findByUserId(String id);
}
UsersService.java
package com.mock.nativecamp.service;
import com.mock.nativecamp.model.Users;
import com.mock.nativecamp.payload.user.PatchReq;
import com.mock.nativecamp.payload.user.SignupReq;
import com.mock.nativecamp.repository.UsersRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Slf4j
@Service
public class UsersService {
@Autowired
private UsersRepository usersRepository;
public Object signupUser(SignupReq signupReq) {
Users user = new Users().signUser(signupReq);
usersRepository.save(user);
return new ResponseEntity(HttpStatus.ACCEPTED);
}
public Object getAllUsers() {
return usersRepository.findAll();
}
public Object getUser(String id) {
return usersRepository.findByUserId(id);
}
public Object updateUser(String userId, PatchReq patchReq) {
Users user = usersRepository.findByUserId(userId);
user.updateUser(user, patchReq);
usersRepository.save(user);
return new ResponseEntity(HttpStatus.ACCEPTED);
}
}
因為修改了model,所以我將db資料清空後來重新測試一次
新增會員
查詢會員
更新會員
再次查詢會員
跟預期的一樣,一定要全帶不然會把其他的也給更新。