backend
API 명세서
data routing

백엔드 마무리?

미래에서 다시보는 입장에서 백엔드가 끝났던 것은 아니었습니다. 하지만 적어도 이당시는 백엔드 작업이 대부분 달성한 것 같아서 프론트엔드를 착수하면 될 것이라고 착각하고 있었습니다.

로그아웃 미들웨어

4-2. 쿠키 설정하기 - 벨로퍼트

로그아웃 기능이 없었고 기능을 찾는 과정에서 유용한 자료를 찾았습니다.

async function signout({ cookies, response }: Context) {
  try {
    const expires = new Date();
    cookies.set('user', null, { expires });
    response.status = 204;
    response.body = null;
  } catch (error) {
    response.status = 400;
    response.body = {
      success: false,
      msg: `${error}`,
    };
  }
}

비교적 간단하게 구현했습니다. access token은 클라이언트 사이드에서 처리하는 것이 좋을 것 같습니다. 자원의 접근을 막이 위해 많은 인증을 요구하는 로직은 이상합니다.

API 명세

API 명세서에서 다른 더 좋은 모범이 있었습니다.

코드스테이트 학생 API 명세서

사용자 비밀번호를 평서문으로 저장한다는 것이 치명적인 문제가 되고 있습니다. 하지만 그것은 API 명세서를 잘 작성한다는 컨텍스트와 무관합니다.

회원관리와 관련된 다양한 API를 제공하고 있습니다. 이부분은 보고 배울 점입니다.

API 명세서 - boostgroup3

사용하고 있는 서비스도 궁금하지만 엄청 긴 명세서에 적합해보이는 형식입니다.

그리고 요청응답 예시 코드가 좋아 보입니다. 마크다운 형식에 적합해 보입니다.

토큰 갱신에 대한 명세

일단 access token이 만료되어 있고 auth 외 요청을 보내면 갱신할 token으로 응답하기로 했습니다. 상당히 단순한 보안 정책으로 시작하고자 합니다.

카카오 로그인 - REST API 명세서

카카오 로그인 명세서를 확인해보니까 갱신요청을 따로 하고 갱신할 token을 받고 갱신하고 다시 요청하는 것이 일반적인 것 같습니다. 나중에 수정하도록 하겠습니다. 갱신 요청에 대한 API를 추가로 구현해야 할 것 같습니다. 그리고 요청 - 만료 응답 - 갱신 요청 - token 응답 - token 갱신 - 재요청 순서로 처리하도록 할 것입니다. 하지만 이번 버전은 아닙니다.

data routing

// Routes.tsx
import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import Layout from './GlobalLayout';
import {
  Cards,
  Deck,
  Landing,
  NotFound,
  Setting,
  SignIn,
  SignUp,
} from '../pages';
import { ROUTE_PATHS } from '../constant/config';

/**
 * 참고 자료
 * @see https://github.com/WANTED-TEAM03/pre-onboarding-10th-1-3/blob/main/src/routes/Routes.tsx
 * @see https://github.com/wanted-frontedend-team5/pre-onboarding-10th-1-5/blob/main/src/router/Router.jsx
 */

const routes = createBrowserRouter([
  {
    path: ROUTE_PATHS.WELCOME,
    element: <Layout />,
    children: [
      { index: true, element: <Landing /> },
      { path: ROUTE_PATHS.SIGN_IN, element: <SignIn /> },
      { path: ROUTE_PATHS.SIGN_UP, element: <SignUp /> },
      { path: ROUTE_PATHS.CARDS, element: <Cards /> },
      { path: ROUTE_PATHS.DECK, element: <Deck /> },
      { path: ROUTE_PATHS.SETTING, element: <Setting /> },
    ],
    errorElement: <NotFound />,
  },
]);

function Router() {
  return <RouterProvider router={routes} />;
}

객체 관계를 갖는 것이 올바른 컴포넌트 관계를 나타냅니다. 과거에는 JSX로 작성했었습니다. 비교적 최근에 적용하는 패턴입니다. Remix에 영감을 받았다고 합니다.

// GlobalLayout.tsx
import { Global } from '@emotion/react';
import GlobalStyle from '../styles/Reset';
import { Navbar } from '../Components';
import { Outlet } from 'react-router-dom';

/**
 * @see https://github.com/WANTED-TEAM03/pre-onboarding-10th-1-3/blob/main/src/routes/_globalLayout.tsx
 */
function Layout() {
  return (
    <>
      <Global styles={GlobalStyle} />
      <Navbar />
      <Outlet />
    </>
  );
}

Outletchildren 역할을 비슷하게 합니다.

// constant/config.ts
export const BASE_URL = 'https://flash-card-backend.deno.dev/api';

export const API_URLS = {
  CARDS: '/card',
  SIGN_IN: '/auth/signin',
  SIGN_UP: '/auth/signup',
};

export const ROUTE_PATHS = {
  WELCOME: '/',
  SIGN_IN: '/signin',
  SIGN_UP: '/signup',
  CARDS: '/cards',
  DECK: '/deck',
  SETTING: '/setting',
};

마지막 상수 객체는 컨텍스트와 무관하지만 data router 스타일로 리팩토링에 성공했습니다.