여기서 2~4번이 checkUserId API, 5번이 signup API에 구현되어야 한다.
/SERVER
index.js
/controller
index.js
/users
checkUserId.js
index.js
signup.js
/routes
users.js
1) checkUserId
Method: POST
Request
[Form Data Parameters] useremail
Response
200: OK
if (res.useremail) {res.json(data)}
else {null}
500: Internal Server Error
err
2) signup
Method: POST
Request
[Headers] Content-Type: application/json
[Form Data Parameters] password, useremail, githubId
Response
200: OK
201: Created
{
"password": "password",
"email": "email",
"githublink": "githublink"
}
500: Internal Server Error
err
SERVER/index.js
세팅된 서버의 index.js에서 각 API 경로를 설정해주었다.
const express = require('express');
const app = express();
const session = require('express-session');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const usersRouter = require('./routes/users');
const reviewsRouter = require('./routes/reviews');
const port = 4000;
app.use(cookieParser());
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: false }));
// app.use(
// cors({
// origin: *,
// methods: ["GET","POST", "OPTION", "PUT"],
// credentials: true
// })
// ) // client주소를 origin에 넣을 필요가 있다.
app.use(
session({
secret: 'safuproject',
resave: false,
saveUninitialized: true,
}),
);
app.get('/', function (req, res) {
res.send('success');
});
app.use('/users', usersRouter);
app.listen(port, () => {
console.log(`server listening on ${port}`);
});
SERVER/routes/users.js
const express = require('express');
const router = express.Router();
const { usersController } = require('../controller');
//POST signup
router.post('/signup', usersController.signup.post);
//POST checkUserId
router.post('/signup/checkId', usersController.checkUserId.post);
module.exports = router;
SERVER/controller/index.js
module.exports = {
usersController: require('./users'),
};
SERVER/controller/users/index.js
여기서부터 컨트롤러와의 여정이 험난해지겠다는 느낌을 살짝 받기 시작했다. SR 때 API를 잘게 쪼개어둔 덕이다. 더 나은 방식이 있을지, 아니면 이번이 첫 프로젝트라 복잡하게 느껴지는건지 모르겠다.
module.exports = {
signup: require('./signup'),
checkUserId: require('./checkUserId'),
};
SERVER/controller/users/checkUserId.js
const { users } = require('../../models');
module.exports = {
post: (req, res) => {
const { useremail } = req.body;
users
.findOne({
where: {
email: useremail,
},
})
.then((data) => {
if (data !== null) {
res.status(201).json(data);
} else {
res.status(201).json(data);
}
})
.catch((err) => {
res.status(500).send('err');
});
},
};
SERVER/controller/users/signup.js
const { users } = require('../../models');
module.exports = {
post: (req, res) => {
const { useremail, password, githubId } = req.body;
users
.create({
useremail: useremail,
password: password,
githubId: githubId,
active: true,
})
.then((data) => {
if (created) {
res.status(201).json(data);
}
})
.catch((err) => {
res.status(500).send('err');
});
},
};
분명 SR 때 회원가입 flow를 정리했었는데도 막상 코드를 작성하려니 모든 과정이 헷갈리기 시작했다. 이전의 sprint들을 통해 회원가입 요청이 들어왔을 때 중복값을 검사하여 기존 회원인 경우 로그인 페이지로 리다이렉트 시키거나, 새로운 회원이면 가입을 시키는 방식에만 익숙했었기 때문이다.
심지어 github 이슈에는 checkUserId를 만들지 않았기에 그런 API가 있었다는 사실을 잊고(!!!) 회원가입만 구현하려니 머리가 좀 아픈 게 아니었다. 결국...
1) findOrCreate로 signup 로직을 짰다가
2) findOne을 이용한 CheckUserId를 추가했다가
3) 다시 두 API를 나누는 과정을 겪어야했다.
*에러와 수정
완성된 코드를 보면 그리 복잡하지 않음에도 잦은 실수가 반복되다보니 마음이 급해져 수정도 여러 차례에 걸쳤다.
1) 우리 팀의 API를 기록한 git book에 따르면 회원가입 시에는 201, 500 코드로만 응답하게 되어 있다. 이미 가입된 회원인 경우, 서버에서 에러가 난 경우 등 회원가입이 되지 않는 모든 응답을 500 에러로 주다 보니 res값이 중복되어 에러코드가 발생했었다.
2) 위의 에러에서도 이미 가입된 회원인 경우 뿐만 아니라 서버 에러가 아닌 모든 경우에는 null값을 클라이언트에 전달했어야 했는데 이 부분을 최초 코드 작성 시에 놓쳤다.
3) 구글링을 하던 중 .spread를 보고 회원가입 로직에 딱 좋겠다 싶어서 적용하였으나 에러가 발생했다. 그때 짠 코드는
.spread((data, created) => {
if (created) {
res.status(201).json(data);
} else {
res.status(500).send('err');
}
})
이렇다. 다시 .then으로 고치니 잘 돌아가서 수정했다. spread가 data를 받고 created를 boolean값으로 처리해준다고 이해했는데, 이 부분에 대한 추가 공부가 필요하다.
4) POSTMAN 사용법에 대해서도 잘 모르고 있었다. POST를 확인하려면 BODY탭에서 key와 value에 fake data라도 넣어줘야 한다. 데이터를 보내주지도 않고 GET마냥 확인하고 있었다.
5) 제일 중요한 부분이라고 할 수도 있는데 user와 users, useremail과 email을 헷갈리지 않고 쓰는 것이다. 사소하면서도 중요한 것들이 헷갈릴 때가 제일 힘들다. 혹시 내가 제대로 파악하지 못한 부분이 있는 건 아닐까 해서. 데이터베이스와 API는 늘 상기하자.
6)
.then((data, created) => {
if (created) {
res.status(201).json(data);
} else {
res.status(500).send('err');
}
})
합쳐져있던 코드를 나누면서 메소드 사용법을 꼼꼼히 숙지하지 않았다. signup에서도 익숙한 findOrCreate를 무심코 쓰다가, create로 바꾼 후에도 문법에 맞도록 코드를 수정하지 않았다. 제발제발 공식문서와 함께 코드를 작성하자.
7)
users
.create({
where: {
useremail: useremail,
}
또 무심코 쓴 부분. checkUserId에서는 회원정보가 최초로 입력되기 때문에 where를 데이터베이스에서 찾을 수 없다. create되어야 할 값만 주면 된다.
다음에는
1. 바로 코드 구현에 들어가지 말고 내가 해야 할 일을 순서대로 정리해본다. 이때 git workflow 명령어와 API(req, res), 연결되는 DB, 지켜야 할 팀 룰을 함께 적어본다.
2. 적어둔 목록이 하나씩 완료될 때마다 보완점 등을 기록한다.
3. 뭘하든 정신차리고 한다.
4. 조급해하지 말 것. 천천히해도 할까말까다.
5. 구글링, 공식문서 참고, 팀원들과의 소통은 아끼지 말자.
➤계속 공부하고 있습니다. 더 나은 의견과 질문이 있으시다면 언제든, 어떤 경로로든 이야기해주세요.