파이썬

[Web API] URL 파라미터 데이터 전송

코샵 2025. 1. 23. 10:08
반응형

소개

웹 개발에서 클라이언트와 서버 간의 데이터 전송 방식 중 하나인 URL 파라미터 방식에 대해 자세히 알아보겠습니다. 이 방식의 장단점, 보안 고려사항, 그리고 프론트엔드에서의 구현 방법까지 상세히 다루겠습니다.

URL 파라미터의 종류

Path Parameters

/api/users/{user_id}/posts/{post_id}
  • 리소스를 식별하는 데 사용
  • URL 경로의 일부로 포함
  • 필수 값으로 처리됨

Query Parameters

/api/users?role=admin&status=active
  • 필터링, 정렬, 페이지네이션에 사용
  • ? 뒤에 key=value 형태로 추가
  • 선택적 값으로 처리됨

프론트엔드 구현

fetch API 사용

// Path Parameters 사용
const getUserDetails = async (userId) => {
  try {
    const response = await fetch(`/api/users/${userId}`, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
      }
    });

    if (!response.ok) {
      throw new Error('User not found');
    }

    return await response.json();
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

// Query Parameters 사용
const searchUsers = async (searchParams) => {
  const params = new URLSearchParams({
    role: searchParams.role,
    status: searchParams.status,
    page: searchParams.page
  });

  try {
    const response = await fetch(`/api/users?${params.toString()}`);
    return await response.json();
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

Axios 사용

import axios from 'axios';

// Path Parameters
const getUserPosts = async (userId, postId) => {
  try {
    const response = await axios.get(`/api/users/${userId}/posts/${postId}`);
    return response.data;
  } catch (error) {
    if (error.response.status === 404) {
      throw new Error('Post not found');
    }
    throw error;
  }
};

// Query Parameters
const searchProducts = async (searchCriteria) => {
  try {
    const response = await axios.get('/api/products', {
      params: {
        category: searchCriteria.category,
        minPrice: searchCriteria.minPrice,
        maxPrice: searchCriteria.maxPrice,
        sort: searchCriteria.sort
      }
    });
    return response.data;
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
};

URL 파라미터 사용의 장점

장점 설명
캐시 가능성 GET 요청은 브라우저에서 자동으로 캐시됨
공유 용이성 URL을 복사하여 쉽게 공유 가능
북마크 가능 사용자가 특정 상태를 북마크할 수 있음
SEO 친화적 검색 엔진이 URL을 이해하고 인덱싱하기 쉬움
구현 간단 서버와 클라이언트 모두에서 처리가 간단

URL 파라미터 사용의 단점

단점 설명
데이터 노출 URL에 모든 파라미터가 노출됨
길이 제한 브라우저와 서버의 URL 길이 제한 존재
보안 취약성 중요 정보가 노출될 수 있음
복잡한 데이터 처리 어려움 복잡한 객체나 배열 전송이 제한적

보안 고려사항

입력 검증

// 프론트엔드 검증
const validateUserId = (userId) => {
  // 숫자만 허용
  const pattern = /^\d+$/;
  if (!pattern.test(userId)) {
    throw new Error('Invalid user ID format');
  }
  return userId;
};

// URL 이스케이프 처리
const safeParam = encodeURIComponent(userInput);

민감 정보 처리

  • 개인식별정보(PII) URL에 포함하지 않기
  • 세션/인증 토큰은 헤더로 전송
  • 중요 파라미터는 POST 요청으로 전환

Rate Limiting

// 프론트엔드 요청 제한
class RequestLimiter {
  constructor(limitPerMinute) {
    this.requests = [];
    this.limitPerMinute = limitPerMinute;
  }

  canMakeRequest() {
    const now = Date.now();
    this.requests = this.requests.filter(time => now - time < 60000);
    return this.requests.length < this.limitPerMinute;
  }

  addRequest() {
    this.requests.push(Date.now());
  }
}

모범 사례

1. URL 설계

// 좋은 예시
/api/users/{userId}/posts/{postId}
/api/products?category=electronics&sort=price

// 나쁜 예시
/api/getUser?id=123
/api/doSomething?action=delete&id=456

2. 에러 처리

const fetchData = async (url) => {
  try {
    const response = await fetch(url);

    if (response.status === 404) {
      throw new Error('Resource not found');
    }

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    return await response.json();
  } catch (error) {
    // 에러 로깅
    console.error('Fetch error:', error);
    // 사용자 친화적 에러 메시지
    throw new Error('Failed to fetch data. Please try again later.');
  }
};

3. 캐싱 전략

const fetchWithCache = async (url) => {
  const cache = await caches.open('my-cache');
  const cachedResponse = await cache.match(url);

  if (cachedResponse) {
    return cachedResponse.json();
  }

  const response = await fetch(url);
  cache.put(url, response.clone());
  return response.json();
};

마치며

URL 파라미터를 통한 데이터 전송은 간단하고 직관적이지만, 보안과 데이터 제한 등을 고려해야 합니다. 적절한 유효성 검사와 보안 조치를 통해 안전하게 구현하는 것이 중요합니다.