--- title: "official-doc / Google AIP-160 — Filtering" source_type: official-doc url: https://google.aip.dev/160 archive_url: vendor: Google related_branches: [feature-api-contract-baseline] related_projects: [ca-skeleton] tags: [official-doc, ca-skeleton, api-design, api-contract, filtering, google-aip] status: raw confidence: high created: 2026-05-31 last_reviewed: 2026-05-31 --- # official-doc / Google AIP-160 — Filtering > Layer: `raw/official-docs/` — 외부 자료(공식 문서)의 **원문 발췌·출처 기록**. > 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관. ## Parent / 활용 branch > 이 자료는 **혼자 존재하지 않는다.** 어느 branch의 구현 결정의 **근거**로서 보관됨. | Branch | 이 자료가 정당화하는 결정 | Decision Evidence Map 상태 | |---|---|---| | [[raw/branch-notes/feature-api-contract-baseline]] | Filter parameter syntax 선택지 중 하나로 Google AIP-160 DSL 의 존재·정의·예제 syntax 를 기록. `flat ?key=value` / `RSQL` / `JSON:API filter[key]` 대비 AIP-160 DSL 의 옵션을 정당화하는 1차 근거. | `UNSUPPORTED_DECISION` — 본 branch 의 Decision Evidence Map 에 B15 (filter syntax 채택) 행이 아직 없음. 본 raw 는 옵션 존재와 예제 syntax 만 기록하며, AIP-160 DSL **채택** 결정 자체는 별도 trade-off 분석 후 branch 에 Decision row 로 신설 필요. | ### Decision Evidence Map 체크 > 본 raw source 가 연결되어야 할 branch Decision 의 현재 상태를 명시한다. hook contract 준수. | 대상 Branch | 연결 대상 Decision ID | 현재 상태 | 해소 조건 | |---|---|---|---| | `feature-api-contract-baseline` | B15 (filter syntax 결정) | `UNSUPPORTED_DECISION` — Decision row 자체가 branch 에 미존재 | branch 에 D19 또는 B15 row 를 신설하고 `Supporting Claims: AIP160-C1, AIP160-C2` 로 연결 시 해소 | **중요**: `AIP160-C1`~`AIP160-C6` 는 AIP-160 DSL 의 *옵션 존재* 와 *syntax 명세* 를 지지한다. DSL 채택 결정(`feature-api-contract-baseline` §Decision Evidence Map 의 미래 row)이 생성되기 전까지 이 raw 는 **evidence pool** 에 있는 상태이며, 어떤 branch decision 의 Supporting Claim 으로도 아직 참조되지 않는다. raw 만으로 "AIP-160 을 채택한다"는 결론을 내리는 것은 금지됨. ## 출처 / Source - 원본 URL: https://google.aip.dev/160 - 아카이브 URL: (미기입) - 저자 / 조직: Google (API Improvement Proposals community) - 발행일: 미확인 (AIP 문서는 버전 이력 없이 갱신됨) - 마지막 확인일: 2026-05-31 ## 왜 저장했는지 / Why archived `feature-api-contract-baseline` 의 §범위에 filtering 이 in-scope 로 listed 됐으나 filter parameter syntax (AIP-160 DSL vs RSQL vs flat `?key=value` vs JSON:API) 의 정확한 결정이 없다. AIP-160 은 Google 이 공식 채택한 filter string DSL 의 명세이므로, 채택 여부 결정을 위한 trade-off 분석 이전에 DSL 의 정의·연산자·예제를 verbatim 으로 보존한다. ## 핵심 인용 / Key quotes (verbatim, 5개) > [§Filtering in list methods] "When employing filtering, a request message should have exactly one filtering field, string filter." > — 위치: AIP-160 §Guidance > Filtering in list methods (line 9 in fetched text) > [§Has operator] "Filtering implementations must provide the : operator, which means 'has'. Its semantics differ based upon the type of the field." > — 위치: AIP-160 §Operators > Has operator (line 61 in fetched text) > [§Schematic validation] "If a non-compliant or schematically invalid filter string is specified, the API should error with INVALID_ARGUMENT." > — 위치: AIP-160 §Operators > Schematic validation (line 78 in fetched text) > [§Negation] "A service that supports negation must support both formats." > — 위치: AIP-160 §Operators > Negation (line 33 in fetched text); 두 formats = `NOT a` 와 `-a` > [§Traversal operator] "The . operator must not be used to traverse through a repeated field." > — 위치: AIP-160 §Operators > Traversal operator (line 58 in fetched text) > [§String values] "String values require quotes if they contain special characters. Single quotes and double quotes are both accepted." > — 위치: AIP-160 §Operators > String values (line 69 in fetched text) ## Claims Extracted / 추출된 주장 > 이 자료가 **직접 말하는 것만** claim 으로 분리한다. 내 프로젝트에 적용한 결론은 여기 쓰지 않는다. | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | AIP160-C1 | AIP-160 은 filtering 을 사용하는 List method 에 대해 `string filter` 라는 단일 필드를 사용하도록 권고한다 | [§Filtering in list methods] "When employing filtering, a request message should have exactly one filtering field, string filter." | `official-reference` | Google AIP 를 준수하는 List method API | `string filter` 외의 복합 파라미터 방식 (예: `?filter[key]=value`) 을 금지하지 않음 — SHOULD 수준 권고 | | AIP160-C2 | AIP-160 DSL 은 `:` (has), `.` (traversal), `=`/`!=`/`<`/`>`/`<=`/`>=` (comparison), `AND`/`OR`/`NOT`/`-` (logical) 연산자를 정의한다. `:` 는 구현 MUST 이며 나머지는 기능별 선택 | [§Has operator] "Filtering implementations must provide the : operator, which means 'has'." | `official-reference` | AIP-160 filter DSL 을 구현하는 서버 | 어떤 언어·프레임워크에서 파싱해야 하는지, 파서 구현 방법 — AIP-160 은 syntax 만 정의 | | AIP160-C3 | AIP-160 을 위반하거나 schema 를 벗어나는 filter string 에 대해 API 는 `INVALID_ARGUMENT` 로 에러 반환해야 한다 (SHOULD) | [§Schematic validation] "If a non-compliant or schematically invalid filter string is specified, the API should error with INVALID_ARGUMENT." | `official-reference` | AIP-160 filter DSL 을 구현하는 서버 | MUST 가 아닌 SHOULD — 구현체가 이를 무시해도 표준 위반이 아님. 에러 메시지 포맷 / gRPC status code 대응은 AIP-160 범위 밖 | | AIP160-C4 | AIP-160 DSL 에서 부정(negation)을 지원하는 서버는 `NOT a` 와 `-a` 두 형식을 모두 MUST 지원해야 한다 | [§Negation] "A service that supports negation must support both formats." | `official-reference` | AIP-160 filter DSL 의 negation 기능을 구현하는 서버 | 부정 기능 자체를 지원해야 한다는 의무는 없음 — 지원 '시' 두 형식 모두 제공해야 함 | | AIP160-C5 | AIP-160 DSL 의 `.` traversal operator 는 repeated field 를 통한 탐색에 사용할 수 없다 (MUST NOT) | [§Traversal operator] "The . operator must not be used to traverse through a repeated field." | `official-reference` | AIP-160 filter DSL 의 traversal operator 를 구현하는 서버 | repeated field 내 개별 요소 조회는 `:` (has) 연산자를 사용 — `.` 과 `:` 의 혼합 사용 패턴은 별도 설명 필요 | | AIP160-C6 | AIP-160 DSL 에서 특수문자를 포함한 string 값은 따옴표 필요. 작은따옴표·큰따옴표 모두 허용 | [§String values] "String values require quotes if they contain special characters. Single quotes and double quotes are both accepted." | `official-reference` | AIP-160 filter string 을 파싱하는 서버와 filter string 을 생성하는 클라이언트 | 특수문자 escape sequence 의 구체적 목록 — 어떤 문자가 '특수문자'인지 명확히 열거되지 않음 | ## Usage Boundaries / 적용 경계 - **이 자료가 직접 증명하는 것**: - `AIP160-C1`: filtering API 에서 `string filter` 단일 필드를 쓰는 것이 Google AIP community 의 공식 권고임 (옵션의 존재 + 예제 syntax) - `AIP160-C2`: AIP-160 DSL 이 정의하는 연산자 목록과 `:` 의 구현 의무 - `AIP160-C3`: 잘못된 filter string 에 대한 `INVALID_ARGUMENT` 에러 반환 권고 - `AIP160-C4`: negation 지원 시 `NOT` 과 `-` 두 형식 모두 제공 의무 - `AIP160-C5`: `.` traversal operator 가 repeated field 에 사용 불가 - `AIP160-C6`: 특수문자 포함 string 값의 따옴표 필요성 - **이 자료가 증명하지 않는 것**: - AIP-160 DSL 이 `feature-api-contract-baseline` 에 채택되어야 한다는 결론 — 채택 결정은 별도 trade-off 분석 필요 (RSQL/FIQL, JSON:API `?filter[key]=value`, flat `?key=value` 와의 비교) - AIP-160 filter DSL 이 RFC/W3C 국제 표준임 — AIP 는 **Google 사내 API community guideline** (`official-reference` 수준). IETF 나 W3C 표준이 아님 - client 와 server 양쪽의 파싱 라이브러리 지원 현황 — AIP-160 은 syntax 만 정의하며 Java/Spring 용 파서는 별도 라이브러리 (예: `google/cel-java`) 필요 - `total_size` 필드 — AIP-160 본문에 해당 내용 없음. pagination 관련 내용은 AIP-158 (Pagination) 참조 - **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: - AIP-160 DSL 채택 vs flat `?key=value` 채택 vs RSQL/FIQL 채택 — 각 옵션의 client/server 구현 부담 비교 (별도 trade-off 분석 문서 필요) - Spring + Java 환경에서 AIP-160 DSL 파서 라이브러리의 성숙도·유지보수성 - ca-skeleton 의 첫 filtering 사용 사례가 무엇인지 (단순 exact-match 인지, 복합 expression 인지) — 오버엔지니어링 여부 판단 ## 메모 / Notes - AIP-160 의 filter DSL 은 Google Cloud API (예: Cloud Asset Inventory, Logging) 에서 실제로 사용되는 DSL 임. Google AIP 는 Google 사내 community guideline 으로 외부 표준이 아님. `official-reference` 수준으로 취급. - `total_size` 필드는 AIP-160 이 아닌 AIP-158 (Pagination) 에서 다룸 — [[raw/official-docs/google-aip-158-pagination.md]] 신설 시 참조. - AIP-160 DSL 이 RFC/W3C 국제 표준이 아니므로, client SDK 가 AIP-160 을 지원하지 않는다면 client 에서 filter string 을 수동으로 조립해야 함 — 이는 DX 부담. - AIP-160 본문에는 OR 가 AND 보다 우선순위가 높다는 비표준적 precedence rule 이 있음 (`a AND b OR c` = `a AND (b OR c)`). 이는 일반 프로그래밍 언어와 반대 — 사용자 혼란 가능성. ## Self-Grep Verification Record 모든 핵심 인용은 `/tmp/source-fetch-20260531091218.txt` 에서 `grep -nF` 로 검증됨: | Quote | Line | Result | |---|---|---| | "a request message should have exactly one filtering field, string filter" | 9, 82 | PASS | | "Filtering implementations must provide the : operator" | 61 | PASS | | "If a non-compliant or schematically invalid filter string is specified, the API should error with INVALID_ARGUMENT" | 78 | PASS | | "A service that supports negation must support both formats" | 33 | PASS | | "The . operator must not be used to traverse through a repeated field" | 58 | PASS | | "String values require quotes if they contain special characters. Single quotes and double quotes are both accepted" | 69 | PASS | 검증한 인용 V: 6 / 일치 P: 6 / 폐기 D: 0 / 정정 C: 0 ## Related / 관련 - 동일 AIP 시리즈 (ordering·pagination·LRO): - [[raw/official-docs/google-aip-132-list-method.md]] — List method 일반 (신설 예정) - [[raw/official-docs/google-aip-158-pagination.md]] — Pagination (신설 예정, `total_size` 필드 포함) - [[raw/official-docs/google-aip-151-long-running-operations.md]] — LRO (신설 예정) - [[raw/official-docs/google-aip-185-resource-versioning]] — Resource versioning (기존) - [[raw/official-docs/api-versioning-google-aip-180]] — Backward compatibility (기존) - 관련 filter syntax 대안 비교: - RSQL/FIQL: 별도 raw 미보관 (trade-off 분석 시 신설 권고) - JSON:API filter: [[raw/official-docs/jsonapi-pagination-format]] (기존, pagination 중심)