iT邦幫忙

2021 iThome 鐵人賽

DAY 9
0

挑戰目標: MockNative Camp前端


今天要來實作更新會員資料API,我的習慣是將request跟response都使用Object class,這樣可以直接做NonNull的檢查以及避免接收到不相關的資料或者是不想要某些欄位被外部更動,像是會員狀態、金幣等等的欄位是不允許被呼叫API更改的。

PatchReq.java 是存放可以被update的欄位,這種用法是我之前在寫Python的習慣,在Python中我會使用marshmallow,更好的是假設有的欄位沒有帶,則會不會出現在dict中,而Java Object宣吿後呼叫時沒有帶的參數會是null如果是boolean則會是false。
我這裡有兩種選擇

  • 只傳修改部分,在Java這邊去判斷每一個是否是Null而boolean則是要檢查是否與原有的一樣
  • 另一種就是由前端傳送所有欄位,如果沒有修改也一樣,而後端就只要直接接收然後更新。

通常都是要跟前端溝通,但前端就是我(淚,所以我們使用第二種方式。
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資料清空後來重新測試一次
新增會員
https://ithelp.ithome.com.tw/upload/images/20210924/201403586Qqhyzd9fM.png

查詢會員
https://ithelp.ithome.com.tw/upload/images/20210924/20140358fypxjIKNLw.png
更新會員
https://ithelp.ithome.com.tw/upload/images/20210924/20140358ngufMKnYNI.png
再次查詢會員
https://ithelp.ithome.com.tw/upload/images/20210924/20140358YuFoU2SqU2.png
跟預期的一樣,一定要全帶不然會把其他的也給更新。


上一篇
[Day 8]開賽八天即遭遇難題(後端篇)
下一篇
[Day 10]怎麼每天都像在趕末班電車R(後端篇)
系列文
關於我快30歲的後端工程師,想轉職成全端工程師,在前端世界中尋求機會的那件事(後端篇)18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言