DataBlock와 실제 API 탐색

발행: (2026년 1월 7일 오전 04:57 GMT+9)
10 min read
원문: Dev.to

It looks like only the source citation was provided, but the article text you’d like translated isn’t included. Could you please paste the content you want translated? I’ll keep the source line unchanged and translate the rest into Korean while preserving the original formatting.

우리가 사용할 것

  • GitHub API – 저장소 통계
  • Packagist API – 다운로드 통계 및 인기 패키지
  • GitHub에서 가져온 원시 composer.json 파일

모든 요청은 Symfony HTTP Client 로 수행되며, DataBlock이 응답을 래핑합니다.

Required packages

composer require hi-folks/data-block symfony/http-client
  • DataBlock – 완전히 프레임워크에 구애받지 않으며, 일반 PHP, Symfony 또는 기타 어떤 설정에서도 동작합니다.
  • Symfony HTTP ClientSymfony\Contracts\HttpClient\HttpClientInterface를 구현합니다.

DataBlock으로 JSON 가져오기

DataBlock은 HTTP JSON 소스를 위한 편리한 헬퍼를 제공합니다:

Block::fromHttpJsonUrl(string $url, HttpClientInterface $client);

이 설계가 중요한 이유

  • 교체 가능한 클라이언트HttpClientInterface의 모든 구현이 작동합니다 (Symfony HttpClient, 모의 클라이언트, 사용자 정의 구현).
  • 테스트 가능한 코드 – 가짜 클라이언트를 주입할 수 있습니다.
  • 디커플링 – 구체적인 클라이언트에 대한 하드코딩된 의존성이 없습니다.
  • 프레임워크 비종속 – DataBlock은 Symfony와 독립적으로 유지됩니다.

HTTP 클라이언트 생성

use HiFolks\DataType\Block;
use Symfony\Component\HttpClient\HttpClient;

$httpClient = HttpClient::create([
    'headers' => [
        'User-Agent' => 'PHP DataBlock',
        'Accept'     => 'application/json',
    ],
]);

이제 이 클라이언트를 DataBlock에 직접 전달할 수 있습니다:

Block::fromHttpJsonUrl($url, $httpClient);

구체적인 예시: Symfony vs. Laravel

두 개의 공개 생태계를 조회합니다:

SourceEndpoint
GitHub – Symfony repohttps://api.github.com/repos/symfony/symfony
GitHub – Laravel repohttps://api.github.com/repos/laravel/framework
Packagist – Symfony statshttps://packagist.org/packages/symfony/symfony/stats.json
Packagist – Laravel statshttps://packagist.org/packages/laravel/framework/stats.json

각 엔드포인트는 많은 중첩 필드를 가진 대용량 JSON 문서를 반환합니다 – DataBlock을 시연하기에 안성맞춤입니다.

데이터 가져오기

// GitHub data
$symfonyGithub = Block::fromHttpJsonUrl(
    'https://api.github.com/repos/symfony/symfony',
    $httpClient,
);
$laravelGithub = Block::fromHttpJsonUrl(
    'https://api.github.com/repos/laravel/framework',
    $httpClient,
);

// Packagist stats
$symfonyStats = Block::fromHttpJsonUrl(
    'https://packagist.org/packages/symfony/symfony/stats.json',
    $httpClient,
);
$laravelStats = Block::fromHttpJsonUrl(
    'https://packagist.org/packages/laravel/framework/stats.json',
    $httpClient,
);

이 시점부터는 원시 배열을 건드리지 않습니다 – DataBlock이 모든 탐색과 형 변환을 담당합니다.

GitHub 통계 표시

// Symfony
echo "Symfony GitHub:\n";
echo "Stars: " . $symfonyGithub->getInt('stargazers_count') . "\n";
echo "Forks: " . $symfonyGithub->getInt('forks_count') . "\n";
echo "Open issues: " . $symfonyGithub->getInt('open_issues_count') . "\n";
echo "Main language: " .
    $symfonyGithub->getString('language', 'unknown') . "\n";

// Laravel
echo "Laravel GitHub:\n";
echo "Stars: " . $laravelGithub->getInt('stargazers_count') . "\n";
echo "Forks: " . $laravelGithub->getInt('forks_count') . "\n";
echo "Open issues: " . $laravelGithub->getInt('open_issues_count') . "\n";
echo "Main language: " .
    $laravelGithub->getString('language', 'unknown') . "\n";

isset() 검사도 없고, PHP 경고도 없으며, 수동 형 변환도 없습니다 – 의도가 명확합니다.

Packagist 다운로드 통계 표시

Packagist의 JSON은 다운로드 수를 downloads 객체 아래에 중첩시킵니다. 일반 배열을 사용하면 여러 번 isset() 검사를 해야 합니다:

$data['downloads']['total'];
$data['downloads']['monthly'];
$data['downloads']['daily'];

DataBlock을 사용하면 점 표기법을 활용할 수 있습니다:

// Symfony downloads
echo "Symfony downloads:\n";
echo "Total:   " . $symfonyStats->getInt('downloads.total') . "\n";
echo "Monthly: " . $symfonyStats->getInt('downloads.monthly') . "\n";
echo "Daily:   " . $symfonyStats->getInt('downloads.daily') . "\n";

// Laravel downloads
echo "Laravel downloads:\n";
echo "Total:   " . $laravelStats->getInt('downloads.total') . "\n";
echo "Monthly: " . $laravelStats->getInt('downloads.monthly') . "\n";
echo "Daily:   " . $laravelStats->getInt('downloads.daily') . "\n";

다시 말해, 깨지기 쉬운 isset() 구조가 없으며 – DataBlock은 안전한 접근과 올바른 타입 변환을 보장합니다.

핵심 요점

  • DataBlock은 깊게 중첩된 JSON 구조를 탐색하는 번거로운 작업을 추상화합니다.
  • Symfony HttpClient는 표준을 준수하고 PSR 호환 HTTP 레이어를 제공하여 DataBlock과 원활하게 작동합니다.
  • 전송(HTTP 클라이언트)과 데이터 처리(DataBlock)를 분리함으로써 코드는 깨끗하고, 테스트 가능하며, 프레임워크에 구애받지 않게 유지됩니다.

Symfony 클라이언트를 HttpClientInterface의 다른 구현으로 자유롭게 교체해도 예제의 나머지 부분은 그대로 작동합니다. 즐거운 코딩 되세요!

Dot‑Notation을 사용한 JSON 작업

echo $elStats->getInt("downloads.daily") . "\n";

여기서 좋은 점은 JSON 구조가 코드에서 거의 사라진다는 것입니다.
구조가 얼마나 깊게 중첩되었는지 신경 쓸 필요 없이, 원하는 값에 대한 경로만 기술하면 됩니다.

  • Dot notation은 깊게 중첩된 문서를 평평하고 읽기 쉬우며 이해하기 쉬운 형태로 바꾸면서도, 안전하고 타입을 인식하는 특성을 유지합니다.

GitHub에서 composer.json 파일 직접 가져오기

$symfonyComposer = Block::fromHttpJsonUrl(
    "https://raw.githubusercontent.com/symfony/symfony/master/composer.json",
    $httpClient,
);
$laravelComposer = Block::fromHttpJsonUrl(
    "https://raw.githubusercontent.com/laravel/framework/master/composer.json",
    $httpClient,
);

getString() 으로 타입이 지정된 (string) 값 가져오기

echo "Symfony PHP requirement: " .
    $symfonyComposer->getString("require.php") .
    "\n";

echo "Laravel PHP requirement: " .
    $laravelComposer->getString("require.php") .
    "\n";

의존성 탐색

$symfonyRequires = $symfonyComposer->getBlock("require");
$laravelRequires = $laravelComposer->getBlock("require");

print_r($symfonyRequires->keys());
print_r($laravelRequires->keys());

이는 구조화된 문서 탐색이며, 단순한 배열 접근이 아닙니다.

구조화된 항목 컬렉션 작업하기

우리가 사용하고 있는 Packagist 엔드포인트는 100개의 가장 인기 있는 패키지 목록을 반환합니다. 즉, 중첩 데이터셋이며 단일 객체가 아닙니다.

$url = "https://packagist.org/explore/popular.json?per_page=100";

$popularPackages = Block::fromHttpJsonUrl($url, $httpClient)
    ->getBlock("packages");

Symfony와 Laravel와 관련된 패키지 선택하기

$symfonyPopularPackages = $popularPackages
    ->where("name", Operator::LIKE, "symfony")
    ->orderBy("favers", "desc");

$laravelPopularPackages = $popularPackages
    ->where("name", Operator::LIKE, "laravel")
    ->orderBy("favers", "desc");

where() 메서드

조건에 따라 데이터셋을 필터링합니다:

->where(field, operator, value)

예시

->where("name", Operator::LIKE, "symfony")

name 필드에 “symfony”라는 단어가 포함된 항목만 남깁니다.
$popularPackages의 각 항목은 자체적으로 구조화된 객체(패키지 엔트리)이며, DataBlock은 이 조건을 모두에 적용합니다.

Operator 열거형

비교가 어떻게 수행되는지를 정의합니다:

Enum의미
Operator::EQUAL동등
Operator::NOT_EQUAL부등
Operator::GREATER_THAN보다 큼
Operator::LESS_THAN보다 작음
Operator::LIKE문자열 포함 (여기서 사용)
…and others…

열거형을 사용하면 원시 문자열 대신 API가:

  • Safer – 오타 없음
  • More explicit – 의도가 명확함
  • Easier to discover – IDE 자동완성 작동

orderBy() 메서드

필터링 후 결과를 정렬합니다:

->orderBy("favers", "desc")

남은 항목들을 favers 필드 기준으로 내림차순 정렬하여 가장 많이 별표된 패키지가 먼저 표시됩니다.

where()orderBy()의 결과는 여전히 Block이므로, 아이템 개수 세기, 중첩 필드 접근, 안전한 값 읽기 등 동일한 도구들을 계속 사용할 수 있습니다.

결과 확인

echo "Popular Packages:\n";

echo "Symfony: " . $symfonyPopularPackages->count() . PHP_EOL;
echo "  High Favers: " .
    $symfonyPopularPackages->getString("0.name", "") .
    " - " .
    $symfonyPopularPackages->getInt("0.favers", 0) .
    PHP_EOL;

echo "Laravel: " . $laravelPopularPackages->count() . PHP_EOL;
echo "  High Favers: " .
    $laravelPopularPackages->getString("0.name", "") .
    " - " .
    $laravelPopularPackages->getInt("0.favers", 0) .
    PHP_EOL;

요약

  • 필터링된 실제 데이터 세트
  • 의미 있는 필드로 정렬된 데이터 세트
  • 카운트하고 결과를 검사함
  • 깊게 중첩된 구조를 탐색

— 모두 원시 배열을 전혀 건드리지 않고.

DataBlock을(를) 사용해야 하는 이유

  • 로컬 배열/파일원격 JSON/YAML(API 응답, 외부 문서) 모두에서 작동합니다.
  • DataBlock으로 래핑하면 다음을 할 수 있습니다:
    • 깊이 중첩된 값을 안전하게 접근
    • 데이터셋 필터링
    • 결과 정렬 및 검사
    • 실제로 필요한 부분만 추출

이 모든 작업을 키가 없거나 구조가 깨지는 경우, 수동 형변환을 신경 쓸 필요 없이 수행할 수 있습니다.

DataBlock은 DTO나 비즈니스 로직을 대체하려는 것이 아닙니다. 그 역할은 간단하고 명확합니다: 어디에서 온 데이터든 구조화된 데이터를 더 쉽고 안전하게 탐색하고, 질의하고, 활용할 수 있게 만드는 것.

References

  • PHP DataBlock GitHub repository
  • Laravel News article
  • 이전 기사Handling Nested PHP Arrays Using DataBlock
Back to Blog

관련 글

더 보기 »