- Web Speech API 등을 활용해 자신만의 외국어 단어장을 제작 및 학습할 수 있는 외국어 학습 웹 어플리케이션
- React.js 를 이용한 프론트엔드 개발
- Express.js 와 MongoDB를 이용한 백엔드 개발
- 2022/07/22 ~
- REST api 의 설계, 구현, 및 통신
- 클라이언트 및 서버 측면의 Session 기반 Authentication/Authorization 구현
- 반복적으로 처리하던 권한 별 페이지 접근 제어 로직을 Route Nesting을 활용해 하나의 Route에서 처리하도록 개선
- Custom hook을 이용한 관심사 분리
- ContextAPI를 이용한 전역상태 관리(Auth상태 및 서버상태(데이터))
- ContextAPI와 useReducer hook을 이용한 FLUX 패턴 구현
- 클라이언트의 http 생성 및 service 호출 로직에 의존성 주입(DI) 패턴을 적용해 프로그램 유연성 향상
- 반복적으로 사용하는 컴포넌트의 재사용성을 높여 생산성 향상
- ToggleButton, SideBar, Modal, 로딩처리, 반응형 웹 등 styled-components를 이용한 다양한 UI구현
- input 입력시 유효성 검사 후 메세지 출력 및 가입버튼이 활성화됩니다.
- 이름을 입력하지 않을 경우 이메일의 앞부분을 이름으로 사용합니다.
- 가입요청시 이메일의 중복 여부를 확인 후 메세지를 출력합니다.
- 가입에 성공시 자동으로 로그인이 진행됩니다.
- 로그인 오류가 발생하면 메세지를 출력합니다.
- email과 password 인증이 완료되면 서버로부터 session-id가 담긴 쿠키를 전송받고 전역 AuthContext의 유저 상태를 업데이트합니다.
- 유저 상태에 따라 client의 route 접근이 제한되고 쿠키의 session-id로 api요청의 인가가 이루어집니다.
- client 유저 상태를 업데이트하고 DB의 세션을 삭제합니다.
- 언어 및 토픽이름을 입력해 새로운 토픽을 생성합니다.
- 선택된 언어는 Web Speech API의 언어설정으로 사용됩니다.
- 토픽 이름과 선택된 읽기언어를 수정할 수 있습니다.
- 토픽을 삭제하면 토픽에 포함되어있는 모든 단어가 삭제됩니다.
- 학습 진행도가 표시됩니다.
- 단어를 생성, 불러오기, 수정 및 삭제할 수 있습니다.
- 전체 단어 혹은 미학습 단어를 선택해 학습합니다.
- 학습이 시작되면 무작위로 단어가 나타납니다.
- 매 단어마다 스스로 학습도를 평가하고 데이터에 반영됩니다. 또한 북마크여부를 수정하거나 발음을 들어볼 수 있습니다.
- 학습종료시 학습 결과를 표시합니다.
- 북마크 되어있는 단어를 한 곳에서 편집하거나 학습할 수 있습니다.
- 미디어쿼리를 이용해 반응형 레이아웃을 구현했습니다.
POST /api/user
Host: 서버지정 CLIENT_URL
{
email: "johndoe@example.com",
password: "password123",
name: "exampleName" // not required
}
HTTP/1.1 201 Created
set-cookie: session-id=exampleid1q2w3e4r
{ msg: "등록성공", userName: "exampleName" }
HTTP/1.1 409 Conflict
Content-Type: application/json
{ msg: "이미 등록된 이메일입니다.", err: Error }
POST /api/session
Host: 서버지정 CLIENT_URL
{
"email": "johndoe@example.com",
"password": "password123"
}
HTTP/1.1 200 OK
set-cookie: session-id=exampleid1q2w3e4r
{ msg: "로그인성공", userName: "name" }
HTTP/1.1 401 Unauthorized
{
msg: "존재하지 않는 아이디입니다.",
errName: "noEmail"
}
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{ msg: "비밀번호가 다릅니다.", errName: "wrongPw" }
DELETE /api/session
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
HTTP/1.1 200 OK
{ msg: "로그아웃 성공" }
GET /api/user
Host: 서버지정 CLIENT_URL
Cookie?: session-id=abcdef1234567890
HTTP/1.1 200 OK
{ userName: "user-name" }
HTTP/1.1 401 Unauthorized
POST /api/topic
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
{ topicName: "my topic", lang: "kr" }
HTTP/1.1 201 Created
{
topics:[
{
topicName:"myTopic",
lang:"kr",
_id:"63f4f5cb5f836047a0a"
}
]
}
GET /api/topic
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
HTTP/1.1 200 OK
{
topics:[
{
topicName:"myTopic",
lang:"kr",
_id:"63f4f5cb5f836047a0a"
}
]
}
DELETE /api/topic/{topicID}
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
HTTP/1.1 200 OK
{
topics:[
{
topicName:"otherTopic",
lang:"kr",
_id:"33f4f5cb336047a0a"
}
]
words:[
{
topic:"wefwe",
topicID:"63f504d2e63350d71b4bf92c",
lang:"en",
word:"wef",
meaning:"wef",
isMemorized:false,
isBookmarked:false,_id:"63f504d4e63350d71b4bf92f"
}
]
}
PATCH /api/topic/{topicID}
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
{
topicName: "newName",
lang: "en"
}
// 수정이 필요한 키만 입력
HTTP/1.1 200 OK
{
topics:[
{
topicName:"newTopic",
lang:"en",
_id:"33f4f5cb336047a0a"
}
]
words:[
{
topic:"wefwe",
topicID:"63f504d2e63350d71b4bf92c",
lang:"en",
word:"wef",
meaning:"wef",
isMemorized:false,
isBookmarked:false,_id:"63f504d4e63350d71b4bf92f"
}
]
}
POST /api/word
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
{
topic: "myTopic"
topicID: "22wef4d2e63350d71b4bf92c"
lang: "en"
word: "give"
meaning: "주다"
}
HTTP/1.1 201 Created
{
words:[
{
topic:"wefwe",
topicID:"63f504d2e63350d71b4bf92c",
lang:"en",
word:"wef",
meaning:"wef",
isMemorized:false,
isBookmarked:false,_id:"63f504d4e63350d71b4bf92f"
}
]
}
GET /api/word
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
HTTP/1.1 200 OK
{
words:[
{
topic:"wefwe",
topicID:"63f504d2e63350d71b4bf92c",
lang:"en",
word:"wef",
meaning:"wef",
isMemorized:false,
isBookmarked:false,_id:"63f504d4e63350d71b4bf92f"
}
]
}
DELETE /api/word/{wordID}
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
HTTP/1.1 200 OK
{
words:[
{
topic:"wefwe",
topicID:"63f504d2e63350d71b4bf92c",
lang:"en",
word:"wef",
meaning:"wef",
isMemorized:false,
isBookmarked:false,_id:"63f504d4e63350d71b4bf92f"
}
]
}
PATCH /api/word/{ID}
Host: 서버지정 CLIENT_URL
Cookie: session-id=abcdef1234567890
{
word: "give"
meaning: "주다"
isBookmarked: false
isMemorized: false
}
// 수정이 필요한 키만 입력
HTTP/1.1 200 OK
{
words:[
{
topic:"wefwe",
topicID:"63f504d2e63350d71b4bf92c",
lang:"en",
word:"wef",
meaning:"wef",
isMemorized:false,
isBookmarked:false,_id:"63f504d4e63350d71b4bf92f"
}
]
}