본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

키 목록 조회하기

원문 보기 위키 갱신

Workers KV 네임스페이스의 모든 키를 나열하는 list() 메서드 사용법을 알아봐요. 접두어 필터링, 페이지네이션, 정렬, 그리고 메타데이터를 활용한 저장 최적화까지 함께 살펴봐요.

출처: 문서

본문

KV 네임스페이스의 모든 키를 나열하려면 Worker 코드에 바인딩한 아무 KV 네임스페이스에서 KV 바인딩의 list() 메서드를 호출하면 돼요:

env.NAMESPACE.list();
await self.env.NAMESPACE.list()

list() 메서드는 값을 얻기 위해 await 할 수 있는 promise를 반환해요.

예시

Worker 안에서 키를 나열하는 예시예요:

export default {
  async fetch(request, env, ctx) {
    try {
      const value = await env.NAMESPACE.list();

      return new Response(JSON.stringify(value.keys), {
        status: 200
      });
    }
    catch (e)
    {
      return new Response(e.message, {status: 500});
    }
  },
};
from workers import WorkerEntrypoint, Response

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        try:
            value = await self.env.NAMESPACE.list()

            return Response.json(value["keys"])
        except Exception as e:
            return Response(str(e), status=500)

참조

KV의 키를 나열하기 위해 제공되는 메서드는 다음과 같아요:

list() 메서드

KV 네임스페이스의 모든 키를 나열하려면 Worker 코드에 바인딩한 아무 KV 네임스페이스에서 KV 바인딩의 list() 메서드를 호출하면 돼요:

env.NAMESPACE.list(options?)
self.env.NAMESPACE.list(options)

매개변수 (Parameters)

  • options: { prefix?: string, limit?: string, cursor?: string }
    • prefix (선택), limit (선택), cursor (선택) 속성을 가진 객체예요.
      • prefix 는 모든 키를 필터링하는 데 사용할 수 있는 접두어를 나타내는 string 이에요.
      • limit 는 반환되는 키의 최대 개수예요. 기본값은 최대치인 1,000개 키예요. 이 기본값을 바꿀 일은 거의 없겠지만 완전성을 위해 포함된 것이에요.
      • cursor 는 응답을 페이지네이션하는 데 사용되는 string 이에요.

응답 (Response)

  • response: Promise<{ keys: { name: string, expiration?: number, metadata?: object }[], list_complete: boolean, cursor: string }>
    • keys, list_complete, cursor 속성을 가진 객체로 resolve되는 Promise 예요.
      • keys 는 나열된 각 키에 대한 객체를 포함하는 배열이에요. 각 객체는 name, expiration (선택), metadata (선택) 속성을 가져요. 키-값 쌍에 만료가 설정되어 있으면 만료가 절대값 형태로 존재하게 돼요 (TTL 형태로 설정되었더라도 마찬가지예요). 키-값 쌍에 null이 아닌 메타데이터가 설정되어 있으면 메타데이터가 존재하게 돼요.
      • list_complete 는 boolean으로, keys 배열이 비어 있더라도 가져올 키가 더 있으면 false 가 돼요.
      • cursor 는 응답을 페이지네이션하는 데 사용되는 string 이에요.

list() 메서드는 다음과 같은 객체로 resolve되는 promise를 반환해요:

{
  "keys": [
    {
      "name": "foo",
      "expiration": 1234,
      "metadata": { "someMetadataKey": "someMetadataValue" }
    }
  ],
  "list_complete": false,
  "cursor": "6Ck1la0VxJ0djhidm1MdX2FyD"
}

keys 속성은 각 키를 설명하는 객체들의 배열을 포함해요. 해당 객체는 1~3개의 키를 가질 수 있어요: 키의 name, 그리고 선택적으로 키의 expiration 과 metadata 값이에요.

name 은 string 이고, expiration 값은 숫자이며, metadata 는 처음에 설정된 타입 그대로예요. expiration 값은 키에 만료가 있는 경우에만 반환되며, TTL 형태로 설정되었더라도 절대값 형태로 반환돼요. metadata 는 주어진 키에 null이 아닌 연관 메타데이터가 있는 경우에만 반환돼요.

list_complete 가 false 이면, keys 배열이 비어 있더라도 가져올 키가 더 있다는 뜻이에요. 더 많은 키를 얻으려면 cursor 속성을 사용하면 돼요. 자세한 내용은 페이지네이션을 참조하세요.

값이 메타데이터 크기 제한에 들어간다면 메타데이터에 값을 저장하는 것을 고려해 보세요. 값을 메타데이터에 저장하는 것은 키마다 list() 후 get() 을 하는 것보다 효율적이에요. put() 을 사용할 때 value 매개변수를 비워 두고 대신 메타데이터 객체에 속성을 포함하세요:

await NAMESPACE.put(key, "", {
  metadata: { value: value },
});
await self.env.NAMESPACE.put(key, "", metadata={"value": value})

변경 사항이 KV 네임스페이스에서 메서드를 호출하는 애플리케이션에 반영되는 데 최대 60초 (또는 get() / getWithMetadata() 메서드의 cacheTtl 에 설정된 값)가 걸릴 수 있어요.

가이드

접두어로 목록 조회하기

특정 접두어로 시작하는 모든 키를 나열해요.

예를 들어 키를 사용자, 사용자 ID, 키 이름으로 콜론으로 구분해 구성했을 수 있어요 (예: user:1:<key>). 다음 코드로 1번 사용자의 키를 가져올 수 있어요:

export default {
  async fetch(request, env, ctx) {
    const value = await env.NAMESPACE.list({ prefix: "user:1:" });
    return new Response(value.keys);
  },
};
from workers import WorkerEntrypoint, Response

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        value = await self.env.NAMESPACE.list(prefix="user:1:")
        return Response(str(value["keys"]))

이렇게 하면 "user:1:" 접두어로 시작하는 모든 키가 반환돼요.

정렬 (Ordering)

키는 항상 UTF-8 바이트에 따라 사전순으로 정렬된 상태로 반환돼요.

페이지네이션 (Pagination)

가져올 키가 더 있으면 list_complete 키가 false 로 설정되고 cursor 도 반환돼요. 이 경우 cursor 값으로 list() 를 다시 호출해 다음 키 배치를 얻을 수 있어요:

const value = await NAMESPACE.list();

const cursor = value.cursor;

const next_value = await NAMESPACE.list({ cursor: cursor });
value = await self.env.NAMESPACE.list()

cursor = value.get("cursor")

next_value = await self.env.NAMESPACE.list(cursor=cursor)

가져올 키가 더 있는지 판단할 때 keys 의 빈 배열을 확인하는 것만으로는 충분하지 않아요. 대신 list_complete 를 사용하세요.

keys 에 빈 배열이 있더라도 가져올 키가 더 있을 수 있어요. 왜냐하면 최근에 만료되었거나 삭제된 키 ↗︎는 반복되어야 하지만 반환되는 keys 에는 포함되지 않기 때문이에요.

큰 결과 집합을 페이지네이션하면서 prefix 인자를 함께 제공하는 경우, 이후 모든 호출에서 초기 인자와 함께 prefix 인자를 제공해야 해요.

list() 작업을 위한 메타데이터로 저장 최적화하기

값이 메타데이터 크기 제한에 들어간다면 메타데이터에 값을 저장하는 것을 고려해 보세요. 값을 메타데이터에 저장하는 것은 키마다 list() 후 get() 을 하는 것보다 효율적이에요. put() 을 사용할 때 value 매개변수를 비워 두고 대신 메타데이터 객체에 속성을 포함하세요:

await NAMESPACE.put(key, "", {
  metadata: { value: value },
});
await self.env.NAMESPACE.put(key, "", metadata={"value": value})

KV에 접근하는 다른 방법

또한 명령줄에서 Wrangler로 키를 나열하거나 REST API로 나열할 수도 있어요.

더 알아보기 (Learn more)

개별 키의 값을 읽거나 쓰는 방법은 읽기 및 쓰기 문서를 참고하세요. 페이지네이션과 정렬 동작은 KV의 실제 저장 구조가 어떻게 동작하는지 설명하는 KV 작동 방식 문서와 함께 보면 이해가 깊어져요.