1919
2020#pragma once
2121
22+ #include < algorithm>
23+ #include < format>
2224#include < memory>
2325#include < string>
2426#include < unordered_map>
2527#include < vector>
2628
2729#include " iceberg/catalog/rest/iceberg_rest_export.h"
30+ #include " iceberg/result.h"
2831#include " iceberg/table_identifier.h"
2932#include " iceberg/type_fwd.h"
33+ #include " iceberg/util/macros.h"
3034
3135// / \file iceberg/catalog/rest/types.h
3236// / Request and response types for Iceberg REST Catalog API.
@@ -38,6 +42,15 @@ struct ICEBERG_REST_EXPORT CatalogConfig {
3842 std::unordered_map<std::string, std::string> defaults; // required
3943 std::unordered_map<std::string, std::string> overrides; // required
4044 std::vector<std::string> endpoints;
45+
46+ // / \brief Validates the CatalogConfig.
47+ Status Validate () const {
48+ // TODO(Li Feiyang): Add an invalidEndpoint test that validates endpoint format.
49+ // See:
50+ // https://github.com/apache/iceberg/blob/main/core/src/test/java/org/apache/iceberg/rest/responses/TestConfigResponseParser.java#L164
51+ // for reference.
52+ return {};
53+ }
4154};
4255
4356// / \brief JSON error payload returned in a response with further details on the error.
@@ -46,36 +59,88 @@ struct ICEBERG_REST_EXPORT ErrorModel {
4659 std::string type; // required
4760 uint32_t code; // required
4861 std::vector<std::string> stack;
62+
63+ // / \brief Validates the ErrorModel.
64+ Status Validate () const {
65+ if (message.empty () || type.empty ()) {
66+ return Invalid (" Invalid error model: missing required fields" );
67+ }
68+
69+ if (code < 400 || code > 600 ) {
70+ return Invalid (" Invalid error model: code {} is out of range [400, 600]" , code);
71+ }
72+
73+ // stack is optional, no validation needed
74+ return {};
75+ }
4976};
5077
5178// / \brief Error response body returned in a response.
5279struct ICEBERG_REST_EXPORT ErrorResponse {
5380 ErrorModel error; // required
81+
82+ // / \brief Validates the ErrorResponse.
83+ // We don't validate the error field because ErrorModel::Validate has been called in the
84+ // FromJson.
85+ Status Validate () const { return {}; }
5486};
5587
5688// / \brief Request to create a namespace.
5789struct ICEBERG_REST_EXPORT CreateNamespaceRequest {
5890 Namespace namespace_; // required
5991 std::unordered_map<std::string, std::string> properties;
92+
93+ // / \brief Validates the CreateNamespaceRequest.
94+ Status Validate () const { return {}; }
6095};
6196
6297// / \brief Update or delete namespace properties request.
6398struct ICEBERG_REST_EXPORT UpdateNamespacePropertiesRequest {
6499 std::vector<std::string> removals;
65100 std::unordered_map<std::string, std::string> updates;
101+
102+ // / \brief Validates the UpdateNamespacePropertiesRequest.
103+ Status Validate () const {
104+ for (const auto & key : removals) {
105+ if (updates.contains (key)) {
106+ return Invalid (" Duplicate key to update and remove: {}" , key);
107+ }
108+ }
109+ return {};
110+ }
66111};
67112
68113// / \brief Request to register a table.
69114struct ICEBERG_REST_EXPORT RegisterTableRequest {
70115 std::string name; // required
71116 std::string metadata_location; // required
72117 bool overwrite = false ;
118+
119+ // / \brief Validates the RegisterTableRequest.
120+ Status Validate () const {
121+ if (name.empty ()) {
122+ return Invalid (" Missing table name" );
123+ }
124+
125+ if (metadata_location.empty ()) {
126+ return Invalid (" Empty metadata location" );
127+ }
128+
129+ return {};
130+ }
73131};
74132
75133// / \brief Request to rename a table.
76134struct ICEBERG_REST_EXPORT RenameTableRequest {
77135 TableIdentifier source; // required
78136 TableIdentifier destination; // required
137+
138+ // / \brief Validates the RenameTableRequest.
139+ Status Validate () const {
140+ ICEBERG_RETURN_UNEXPECTED (source.Validate ());
141+ ICEBERG_RETURN_UNEXPECTED (destination.Validate ());
142+ return {};
143+ }
79144};
80145
81146// / \brief An opaque token that allows clients to make use of pagination for list APIs.
@@ -87,6 +152,14 @@ struct ICEBERG_REST_EXPORT LoadTableResult {
87152 std::shared_ptr<TableMetadata> metadata; // required
88153 std::unordered_map<std::string, std::string> config;
89154 // TODO(Li Feiyang): Add std::shared_ptr<StorageCredential> storage_credential;
155+
156+ // / \brief Validates the LoadTableResult.
157+ Status Validate () const {
158+ if (!metadata) {
159+ return Invalid (" Invalid metadata: null" );
160+ }
161+ return {};
162+ }
90163};
91164
92165// / \brief Alias of LoadTableResult used as the body of CreateTableResponse
@@ -99,31 +172,46 @@ using LoadTableResponse = LoadTableResult;
99172struct ICEBERG_REST_EXPORT ListNamespacesResponse {
100173 PageToken next_page_token;
101174 std::vector<Namespace> namespaces;
175+
176+ // / \brief Validates the ListNamespacesResponse.
177+ Status Validate () const { return {}; }
102178};
103179
104180// / \brief Response body after creating a namespace.
105181struct ICEBERG_REST_EXPORT CreateNamespaceResponse {
106182 Namespace namespace_; // required
107183 std::unordered_map<std::string, std::string> properties;
184+
185+ // / \brief Validates the CreateNamespaceResponse.
186+ Status Validate () const { return {}; }
108187};
109188
110189// / \brief Response body for loading namespace properties.
111190struct ICEBERG_REST_EXPORT GetNamespaceResponse {
112191 Namespace namespace_; // required
113192 std::unordered_map<std::string, std::string> properties;
193+
194+ // / \brief Validates the GetNamespaceResponse.
195+ Status Validate () const { return {}; }
114196};
115197
116198// / \brief Response body after updating namespace properties.
117199struct ICEBERG_REST_EXPORT UpdateNamespacePropertiesResponse {
118200 std::vector<std::string> updated; // required
119201 std::vector<std::string> removed; // required
120202 std::vector<std::string> missing;
203+
204+ // / \brief Validates the UpdateNamespacePropertiesResponse.
205+ Status Validate () const { return {}; }
121206};
122207
123208// / \brief Response body for listing tables in a namespace.
124209struct ICEBERG_REST_EXPORT ListTablesResponse {
125210 PageToken next_page_token;
126211 std::vector<TableIdentifier> identifiers;
212+
213+ // / \brief Validates the ListTablesResponse.
214+ Status Validate () const { return {}; }
127215};
128216
129217} // namespace iceberg::rest
0 commit comments