API 모듈: Rhymix를 위한 완벽한 RESTful JSON API으로

API 모듈: Rhymix를 위한 완벽한 RESTful JSON API

이온디 14

TL;DR

  • 25개 이상의 RESTful API 엔드포인트
  • React/Vue/Flutter 등 어디서든 사용 가능
  • CORS + 세션 기반 안전한 인증
  • 레이아웃 페이지에서도 동작하는 댓글 시스템
  • 게시판, 회원, 댓글, 추천, 마이페이지 완벽 지원

들어가며: React 스킨의 숙제

Rhymix로 React 게시판 스킨을 만들면서 가장 큰 벽은 무엇이었을까요?

<!-- Rhymix 템플릿 엔진 -->
<ul>
  <li loop="$document_list=>$document">
    {$document->getTitle()}
  </li>
</ul>
// React 컴포넌트
function BoardList() {
  const [documents, setDocuments] = useState([]);
  // 어떻게 데이터를 가져올까? 
}

템플릿 엔진과 React의 충돌 - SSR(서버 사이드 렌더링)과 CSR(클라이언트 사이드 렌더링)의 불일치 - 기존 proc* 액션들은 HTML 리다이렉트 방식 - JSON 데이터를 직접 가져올 방법이 없음

"JSON API가 있다면 얼마나 좋을까?"

이 절실한 필요에서 API 모듈이 탄생했습니다.


API 모듈이 해결한 문제들

문제 1: React/Vue 스킨 개발의 어려움

기존 방식

// procBoardInsertComment 호출
exec_json('procBoardInsertComment', {
  document_srl: 123,
  content: '댓글'
});
// → 게시판 모듈 컨텍스트가 없으면 실패
// → 레이아웃 페이지에서 사용 불가

API 모듈 방식

// REST API 호출
fetch('/modules/api/rest.php?type=comment_insert&document_srl=123', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ content: '댓글' }),
  credentials: 'same-origin'
});
// → 어디서든 동작!
// → 게시판 스킨, 레이아웃 페이지, 위젯 모두 OK

문제 2: 크로스 플랫폼 앱 개발

기존 방식 - Rhymix는 웹 전용 - 모바일 앱이나 데스크톱 앱 개발 어려움 - 데이터를 가져올 표준 방법 없음

API 모듈 방식

// 동일한 API를 모든 플랫폼에서 사용
const API = 'https://eond.com/modules/api/rest.php';

// React Native (모바일 앱)
fetch(`${API}?type=document_list&mid=board`)

// Flutter (iOS/Android)
http.get(Uri.parse('${API}?type=document_list&mid=board'))

// Electron (데스크톱 앱)
fetch(`${API}?type=document_list&mid=board`)

하나의 API로 모든 플랫폼 지원!

문제 3: HTML 응답 vs JSON 응답

기존 Rhymix proc* 액션

// procBoardInsertDocument 호출
const response = await fetch('/index.php', {
  method: 'POST',
  body: formData
});

// 응답: HTML 페이지 (리다이렉트)
// JSON 파싱 시도 → SyntaxError 발생!

API 모듈

// REST API 호출
const response = await fetch('/modules/api/rest.php?type=document_insert', {
  method: 'POST',
  body: JSON.stringify(data)
});

// 응답: 항상 JSON
const result = await response.json();
// {
//   "status": 1,
//   "message": "성공",
//   "data": { "document_srl": 123 }
// }

일관된 JSON 응답 형식!


API 모듈의 완벽한 기능

1. 게시판 API

게시글 목록 조회

GET /api?mid=board&act=dispApiDocumentList&page=1

// 파라미터
- page: 페이지 번호
- list_count: 페이지당 개수
- search_target: 검색 대상 (title, content, nick_name)
- search_keyword: 검색 키워드
- category_srl: 카테고리 필터
- sort_index: 정렬 기준 (list_order, regdate, readed_count)
- order_type: 정렬 방향 (asc, desc)

응답 예시

{
  "status": 1,
  "message": "성공",
  "payload": {
    "documents": [
      {
        "document_srl": 123,
        "title": "게시글 제목",
        "content": "게시글 요약...",
        "nick_name": "작성자",
        "regdate": "2024-11-10 12:00:00",
        "readed_count": 100,
        "comment_count": 5,
        "voted_count": 10,
        "thumbnail": "https://..."
      }
    ],
    "total_count": 150,
    "total_page": 8,
    "page": 1,
    "list_count": 20,
    "categories": [...],
    "grant": {
      "list": true,
      "view": true,
      "write_document": true,
      "write_comment": true
    }
  }
}

게시글 상세 조회

GET /api?mid=board&act=dispApiDocument&document_srl=123

// 파라미터
- document_srl: 게시글 번호 (필수)
- skip_view_count: true면 조회수 증가  

응답 예시

{
  "status": 1,
  "message": "성공",
  "payload": {
    "document": {
      "document_srl": 123,
      "title": "게시글 제목",
      "content": "게시글 전체 내용...",
      "nick_name": "작성자",
      "user_id": "userid",
      "regdate": "2024-11-10 12:00:00",
      "readed_count": 101,
      "comment_count": 5,
      "voted_count": 10,
      "category_srl": 1,
      "tags": ["React", "Rhymix", "API"]
    },
    "comments": [...],
    "files": [...],
    "prev_document": {
      "document_srl": 122,
      "title": "이전글 제목"
    },
    "next_document": {
      "document_srl": 124,
      "title": "다음글 제목"
    },
    "grant": {
      "view": true,
      "write_comment": true,
      "is_granted": false
    }
  }
}

스마트 이전글/다음글 필터링

API 모듈은 카테고리와 태그를 기반으로 관련된 이전글/다음글을 찾습니다:

현재 문서:
- 카테고리: "프로젝트"
- 태그: "React, TypeScript, API"

1차 시도 (필터링):
→ 같은 카테고리 + 공통 태그가 있는 문서

2차 시도 (Fallback):
→ 1차에서 결과 없으면 전체 게시판에서 찾기

게시글 작성

POST /modules/api/rest.php?type=document_insert

// Body (JSON)
{
  "mid": "board",
  "title": "게시글 제목",
  "content": "게시글 내용",
  "category_srl": 1,         // 선택
  "is_secret": "N",          // 비밀글 여부
  "tags": "React,API"        // 선택
}

// 응답
{
  "status": 1,
  "message": "게시글이 등록되었습니다.",
  "data": {
    "document_srl": 123
  }
}

게시글 수정/삭제

// 수정
POST /modules/api/rest.php?type=document_update
{
  "document_srl": 123,
  "title": "수정된 제목",
  "content": "수정된 내용"
}

// 삭제
POST /modules/api/rest.php?type=document_delete
{
  "document_srl": 123
}

2. 댓글 API

왜 레이아웃 페이지에서도 동작하나?

핵심은 독립적인 엔드포인트executeQuery 직접 사용입니다.

// API 모듈의 댓글 등록 (rest.php)
case 'comment_insert':
    // 1. 세션에서 로그인 정보 가져오기
    $logged_info = Context::get('logged_info');

    // 2. executeQuery로 직접 DB에 삽입
    $output = executeQuery(
        'insertComment',
        $comment_args
    );

    // 3. JSON 응답 반환
    echo json_encode([
        'status' => 1,
        'message' => '댓글이 등록되었습니다.',
        'data' => ['comment_srl' => $comment_srl]
    ]);
    // → 게시판 모듈 컨텍스트 불필요!

댓글 작성

POST /modules/api/rest.php?type=comment_insert&document_srl=123

// Body (JSON)
{
  "content": "댓글 내용",
  "parent_srl": 0  // 대댓글이면 부모 댓글 번호
}

// 응답
{
  "status": 1,
  "message": "댓글이 등록되었습니다.",
  "data": {
    "comment_srl": 456
  }
}

보안 체크 - ✅ 로그인 필수 (세션 기반) - ✅ 게시글 존재 여부 확인 - ✅ 댓글 권한 체크 - ✅ SQL Injection 방지 (prepared statement) - ✅ XSS 방지 (출력 이스케이프)

댓글 수정/삭제

// 수정
POST /modules/api/rest.php?type=comment_update
{
  "comment_srl": 456,
  "content": "수정된 내용"
}

// 삭제
POST /modules/api/rest.php?type=comment_delete
{
  "comment_srl": 456
}

권한 체크 - 댓글 작성자 또는 관리자만 수정/삭제 가능

3. 추천/비추천 API

// 게시글 추천
POST /modules/api/rest.php?type=vote_up&document_srl=123

// 게시글 비추천
POST /modules/api/rest.php?type=vote_down&document_srl=123

// 추천/비추천 취소
POST /modules/api/rest.php?type=vote_cancel&document_srl=123

// 응답
{
  "status": 1,
  "message": "추천하였습니다.",
  "data": {
    "voted_count": 11  // 현재 추천 수
  }
}

4. 회원 인증 API

비밀번호 찾기

POST /modules/api/rest.php?type=password_reset_request

// Body (JSON)
{
  "user_id": "사용자아이디",
  "email_address": "user@example.com"
}

// 응답
{
  "status": 1,
  "message": "비밀번호 재설정 링크가 이메일로 발송되었습니다."
}

동작 방식 1. 아이디와 이메일 주소 일치 확인 2. 1시간 유효한 인증 토큰 생성 3. 이메일로 재설정 링크 발송

회원가입

POST /modules/api/rest.php?type=member_signup

// Body (JSON)
{
  "user_id": "userid",
  "password": "비밀번호123",
  "password_confirm": "비밀번호123",
  "email_address": "user@example.com",
  "nick_name": "닉네임",
  "user_name": "이름",
  "allow_mailing": "Y",     // 메일 수신 동의
  "allow_message": "Y"      // 쪽지 수신 동의
}

// 응답
{
  "status": 1,
  "message": "회원가입이 완료되었습니다.",
  "data": {
    "member_srl": 12345,
    "require_confirm": false  // 이메일 인증 필요 여부
  }
}

검증 - 비밀번호: 최소 8자, 영문+숫자 포함 - 아이디, 이메일, 닉네임 중복 체크 - 이메일 인증 설정 시 인증 메일 발송

5. 마이페이지 API

내 정보 조회

GET /modules/api/rest.php?type=member_my_info

// 응답
{
  "status": 1,
  "message": "성공",
  "data": {
    "member_srl": 12345,
    "user_id": "userid",
    "nick_name": "닉네임",
    "user_name": "홍길동",
    "email_address": "user@example.com",
    "profile_image": "https://eond.com/files/member_extra_info/profile.jpg",
    "regdate": "2024-01-15 10:00:00",
    "last_login": "2025-12-03 09:30:00",
    "point": 1500,
    "level": 5
  }
}

포인트 히스토리

GET /modules/api/rest.php?type=member_point_history&page=1

// 응답
{
  "status": 1,
  "message": "성공",
  "data": {
    "current_point": 1500,
    "history": [
      {
        "point_srl": 789,
        "point": 100,              // 증감량 (+ 적립, - 차감)
        "accumulated_point": 1500, // 해당 시점 누적
        "comment": "게시글 작성",
        "regdate": "2025-12-03 10:00:00"
      },
      {
        "point_srl": 788,
        "point": -50,
        "accumulated_point": 1400,
        "comment": "댓글 작성",
        "regdate": "2025-12-02 15:30:00"
      }
    ],
    "total_count": 150,
    "total_page": 8,
    "page": 1
  }
}

프로필 이미지 변경

POST /modules/api/rest.php?type=member_update_profile_image
Content-Type: multipart/form-data

FormData:
  profile_image: [이미지 파일]

// 응답
{
  "status": 1,
  "message": "프로필 이미지가 변경되었습니다.",
  "data": {
    "profile_image": "https://eond.com/files/member_extra_info/..."
  }
}

제한 - 파일 형식: JPG, PNG, GIF, WebP - 최대 크기: 5MB

비밀번호 변경

POST /modules/api/rest.php?type=member_update_password

// Body (JSON)
{
  "current_password": "현재비밀번호",
  "new_password": "새비밀번호123",
  "new_password_confirm": "새비밀번호123"
}

// 응답
{
  "status": 1,
  "message": "비밀번호가 변경되었습니다."
}

개인정보 수정

POST /modules/api/rest.php?type=member_update_info

// Body (JSON)
{
  "nick_name": "새닉네임",
  "user_name": "새이름",
  "email_address": "new@example.com",
  "allow_mailing": "Y",
  "allow_message": "N"
}

// 응답
{
  "status": 1,
  "message": "개인정보가 수정되었습니다.",
  "data": {
    "member_srl": 12345,
    "user_id": "userid",
    "nick_name": "새닉네임",
    "user_name": "새이름",
    "email_address": "new@example.com",
    "profile_image": "..."
  }
}

활동 내역 조회

// 내가 쓴 글
GET /modules/api/rest.php?type=member_my_documents&page=1&list_count=20&mid=board

// 내가 쓴 댓글
GET /modules/api/rest.php?type=member_my_comments&page=1&list_count=20

// 스크랩한 글
GET /modules/api/rest.php?type=member_my_scraps&page=1&list_count=20

6. 인기글 API

GET /modules/api/rest.php?type=popular_documents
  &mid=board
  &page=1
  &list_count=20
  &period=7
  &sort_by=readed_count

// 파라미터
- mid: 게시판 mid (필수)
- page: 페이지 번호 (기본 1)
- list_count: 페이지당 개수 (기본 20)
- period: 기간 ( 단위, 기본 7)
- sort_by: 정렬 기준
  * readed_count: 조회수 (기본)
  * voted_count: 추천수
  * comment_count: 댓글수

// 응답
{
  "status": 1,
  "message": "성공",
  "data": {
    "documents": [
      {
        "document_srl": 123,
        "title": "인기글 제목",
        "content": "요약...",
        "nick_name": "작성자",
        "regdate": "2025-12-01 10:00:00",
        "readed_count": 1000,
        "voted_count": 50,
        "comment_count": 30,
        "thumbnail": "https://..."
      }
    ],
    "total_count": 100,
    "total_page": 5,
    "page": 1,
    "period": 7,
    "sort_by": "readed_count"
  }
}

실전 활용 예시

예시 1: React 게시판 스킨

// TypeScript + React Hooks
import React, { useState, useEffect } from 'react';

interface Document {
  document_srl: number;
  title: string;
  content: string;
  nick_name: string;
  regdate: string;
  readed_count: number;
  comment_count: number;
}

function BoardList({ mid }: { mid: string }) {
  const [documents, setDocuments] = useState<Document[]>([]);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);

  useEffect(() => {
    fetchDocuments();
  }, [page]);

  const fetchDocuments = async () => {
    try {
      const response = await fetch(
        `/api?mid=${mid}&act=dispApiDocumentList&page=${page}`
      );
      const data = await response.json();

      if (data.status === 1) {
        setDocuments(data.payload.documents);
      }
    } catch (error) {
      console.error('Error fetching documents:', error);
    } finally {
      setLoading(false);
    }
  };

  if (loading) {
    return <div className="loading">로딩 ...</div>;
  }

  return (
    <div className="board-list">
      {documents.map(doc => (
        <article key={doc.document_srl} className="document-item">
          <h2>
            <a href={`/board/${doc.document_srl}`}>
              {doc.title}
            </a>
          </h2>
          <p className="content">{doc.content}</p>
          <div className="meta">
            <span className="author">{doc.nick_name}</span>
            <span className="date">{doc.regdate}</span>
            <span className="views">조회 {doc.readed_count}</span>
            <span className="comments">댓글 {doc.comment_count}</span>
          </div>
        </article>
      ))}

      <div className="pagination">
        <button onClick={() => setPage(p => p - 1)} disabled={page === 1}>
          이전
        </button>
        <span>페이지 {page}</span>
        <button onClick={() => setPage(p => p + 1)}>
          다음
        </button>
      </div>
    </div>
  );
}

export default BoardList;

예시 2: 레이아웃 페이지에 댓글 추가

// 홈페이지(레이아웃 페이지)에 댓글 시스템 추가

// 댓글 목록 로드
async function loadComments(documentSrl) {
    const response = await fetch(
        `/api?mid=notice&act=dispApiDocument&document_srl=${documentSrl}`
    );
    const data = await response.json();

    if (data.status === 1) {
        displayComments(data.payload.comments);
    }
}

// 댓글 작성
async function submitComment(documentSrl, content) {
    const response = await fetch(
        `/modules/api/rest.php?type=comment_insert&document_srl=${documentSrl}`,
        {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ content: content }),
            credentials: 'same-origin'  // 쿠키(세션) 전송 필수!
        }
    );

    const result = await response.json();

    if (result.status === 1) {
        alert('댓글이 등록되었습니다.');
        loadComments(documentSrl);  // 댓글 목록 새로고침
    } else {
        alert('댓글 등록 실패: ' + result.message);
    }
}

// 사용 예시
document.getElementById('comment-form').addEventListener('submit', (e) => {
    e.preventDefault();
    const content = document.getElementById('comment-content').value;
    const documentSrl = 123;  // 게시글 번호

    submitComment(documentSrl, content);
});

예시 3: 모바일 앱 (React Native)

// React Native로 Rhymix 게시판 앱 만들기
import React, { useState, useEffect } from 'react';
import { View, Text, FlatList, TouchableOpacity } from 'react-native';

const API_URL = 'https://eond.com/modules/api/rest.php';

function BoardScreen() {
  const [documents, setDocuments] = useState([]);

  useEffect(() => {
    fetchDocuments();
  }, []);

  const fetchDocuments = async () => {
    try {
      const response = await fetch(
        `https://eond.com/api?mid=board&act=dispApiDocumentList`
      );
      const data = await response.json();
      setDocuments(data.payload.documents);
    } catch (error) {
      console.error(error);
    }
  };

  const vote = async (documentSrl) => {
    const response = await fetch(
      `${API_URL}?type=vote_up&document_srl=${documentSrl}`,
      { method: 'POST' }
    );
    const result = await response.json();
    alert(result.message);
  };

  return (
    <FlatList
      data={documents}
      keyExtractor={item => item.document_srl.toString()}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text style={styles.title}>{item.title}</Text>
          <Text>{item.content}</Text>
          <TouchableOpacity onPress={() => vote(item.document_srl)}>
            <Text> 추천 {item.voted_count}</Text>
          </TouchableOpacity>
        </View>
      )}
    />
  );
}

보안 및 성능

보안 기능

1. CORS (Cross-Origin Resource Sharing)

// 허용된 도메인만 API 접근 가능
$allowed_origins = [
    'https://eond.com',
    'http://localhost:3000'  // 개발용
];

2. 세션 기반 인증

// 쿠키(세션) 전송 필수
fetch('/modules/api/rest.php?type=comment_insert', {
    method: 'POST',
    credentials: 'same-origin'  // 중요!
});

3. SQL Injection 방지

// executeQuery = PDO prepared statement
$output = executeQuery('insertComment', $args);
// → 자동으로 이스케이프 처리

4. XSS 방지

// 출력 시 자동 이스케이프
$comment->content = htmlspecialchars($content);

5. 권한 체크

// 댓글 수정/삭제 시 작성자 확인
if (!$oComment->isGranted()) {
    return ['status' => 0, 'message' => '권한이 없습니다.'];
}

성능 최적화

1. 효율적인 쿼리

<!-- getDocumentList.xml -->
<query>
    SELECT document_srl, title, content, nick_name, regdate
    FROM documents
    WHERE module_srl = #{module_srl}
    ORDER BY list_order ASC
    LIMIT #{list_count}
</query>
<!-- 필요한 컬럼만 조회 -->

2. 페이징 처리

// 대용량 데이터도 빠른 응답
GET /api?mid=board&page=1&list_count=20
// → 20개씩만 조회

3. JSON 직렬화 최적화

// 불필요한 데이터 제거
unset($document->variables);
unset($document->_filter);

echo json_encode($data, JSON_UNESCAPED_UNICODE);

설치 및 시작하기

시스템 요구사항

필수 - Rhymix 2.0 이상 - PHP 7.4 이상 - PDO 확장 모듈 - JSON 지원

권장 - PHP 8.0 이상 - HTTPS 환경 - Gzip 압축 활성화

설치 방법

1. 모듈 다운로드

# Git으로 다운로드
git clone https://github.com/eond/api.git modules/api

# 또는 ZIP 파일 다운로드 후 압축 해제

2. 관리자 설정

1. 관리자 페이지 접속
   http://yoursite.com/index.php?module=admin&act=dispApiAdminConfig

2. REST API 설정
   - CORS 도메인 추가
   - API 활성화

3. 저장

3. API 테스트

# 게시글 목록 조회
curl http://yoursite.com/api?mid=board&act=dispApiDocumentList

# 응답 확인
{
  "status": 1,
  "message": "성공",
  "payload": { ... }
}

개발 환경 설정

React 프로젝트에서 사용

// src/api/board.js
const API_BASE = '/api';
const REST_API = '/modules/api/rest.php';

export const boardAPI = {
  // 게시글 목록
  getDocuments: async (mid, page = 1) => {
    const response = await fetch(
      `${API_BASE}?mid=${mid}&act=dispApiDocumentList&page=${page}`
    );
    return response.json();
  },

  // 댓글 작성
  addComment: async (documentSrl, content) => {
    const response = await fetch(
      `${REST_API}?type=comment_insert&document_srl=${documentSrl}`,
      {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content }),
        credentials: 'same-origin'
      }
    );
    return response.json();
  }
};

버전 히스토리

v1.1.0 (2024-11-10) - 최신

  • ✨ 마이페이지 API 추가
    • 내 정보 조회
    • 포인트 히스토리
    • 프로필 이미지 변경
    • 비밀번호 변경
    • 개인정보 수정
    • 내가 쓴 글/댓글 목록
    • 스크랩한 글 목록
  • ✨ 회원 인증 API 추가
    • 비밀번호 찾기
    • 회원가입
  • ✨ 인기글 API 추가

v1.0.0 (2024-10-01)

  • API 모듈 첫 출시
  • ✨ 게시판 API (목록, 상세, 작성, 수정, 삭제)
  • ✨ 댓글 API (작성, 수정, 삭제)
  • ✨ 추천/비추천 API
  • ✨ CORS 지원
  • ✨ 세션 기반 인증

로드맵

v1.2.0 (예정)

  • [ ] GraphQL 지원
  • [ ] 웹소켓 실시간 알림
  • [ ] 파일 업로드 API
  • [ ] 배치 작업 API

v2.0.0 (장기)

  • [ ] OAuth 2.0 인증
  • [ ] API 버전 관리
  • [ ] Rate Limiting
  • [ ] API 문서 자동 생성

FAQ

Q1. 기존 게시판 스킨과 호환되나요?

A. 네, API 모듈은 기존 게시판 스킨과 독립적으로 동작합니다. 기존 스킨을 유지하면서 새로운 React 스킨을 추가로 개발할 수 있습니다.

Q2. 모바일 앱에서 사용할 수 있나요?

A. 네, React Native, Flutter, Swift, Kotlin 등 모든 플랫폼에서 사용 가능합니다. RESTful API 표준을 따르므로 HTTP 요청만 가능하면 됩니다.

Q3. 보안은 안전한가요?

A. 네, CORS, 세션 인증, SQL Injection 방지, XSS 방지 등 모든 보안 기능이 구현되어 있습니다. PDO prepared statement로 DB를 안전하게 처리합니다.

Q4. 성능은 어떤가요?

A. 효율적인 쿼리와 JSON 직렬화로 빠른 응답 속도를 보장합니다. 페이징 처리로 대용량 데이터도 문제없습니다.

Q5. 라이선스는?

A. 상업용 유료 라이선스입니다. 구매 후 소스코드, 기술 지원, 업데이트를 제공받으실 수 있습니다. 자세한 사항은 https://eond.com 또는 admin@eond.com으로 문의해주세요.

Q6. 커스텀 API를 추가할 수 있나요?

A. 네, rest.php에 새로운 case를 추가하면 됩니다. 기존 API를 참고하여 쉽게 확장할 수 있습니다.


사용자 후기 (테스트 사용자)

"React로 게시판을 만들고 싶었는데, 데이터를 가져올 방법이 없어서 포기했었어요. API 모듈 덕분에 드디어 해냈습니다!" — React 개발자 K

"레이아웃 페이지에서 댓글이 안 돼서 고민했는데, REST API로 간단하게 해결됐어요. 정말 편합니다." — 커뮤니티 관리자 L

"Flutter로 모바일 앱을 만들고 있는데, API 모듈이 없었다면 불가능했을 겁니다. 감사합니다!" — 앱 개발자 P


라이선스 및 구매

API 모듈은 상업용 유료 라이선스 제품입니다.

구매 정보 - 가격: 문의 필요 - 구매 문의: https://eond.com 또는 admin@eond.com - 포함 사항: 소스코드, 기술 지원, 업데이트

지원 서비스 - 설치 및 설정 지원 - 기술 지원 (이메일, 포럼) - 무료 업데이트 (1년간) - 사용자 가이드 및 API 문서 제공


결론

API 모듈은 Rhymix의 가능성을 확장합니다.

API 모듈이 제공하는 가치

React/Vue 스킨 개발: 완벽한 JSON API ✅ 크로스 플랫폼: 웹, 모바일, 데스크톱 앱 ✅ 독립적인 엔드포인트: 어디서든 동작 ✅ 표준 준수: RESTful API ✅ 보안: CORS + 세션 인증

지금 바로 시작하세요

React로 게시판을 만들고 싶으셨나요? 레이아웃 페이지에 댓글을 추가하고 싶으셨나요? 모바일 앱을 개발하고 싶으셨나요?

API 모듈이 모든 것을 가능하게 합니다.

다운로드: https://github.com/eond/api API 문서: modules/api/README.md 데모: https://demo.eond.com/api 문의: admin@eond.com


작성일: 2025-12-03 카테고리: Rhymix, 모듈, API 태그: #API #Rhymix #JSON #RESTful #React #Vue #모바일앱 버전: API 모듈 v1.1.0