Qore RestSchemaValidator Module Reference 2.2
Loading...
Searching...
No Matches
RestSchemaValidator.qm.dox.h
1// -*- mode: c++; indent-tabs-mode: nil -*-
3
4/* RestSchemaValidator.qm Copyright (C) 2017 - 2023 Qore Technologies, s.r.o.
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23*/
24
25
26// make sure we have the required qore version
27
28// requires the HttpServerUtil module
29
30// need mime definitions
31
32// supports using the DataProvider module to describe input and output records
33
34// supports logging with the Logger module
35
36
37
38
39
113 public hashdecl RestRequestClientInfo {
115 string uri_path;
117 string content;
119
121 *list<string> response_content;
123 *data body;
124 };
125
127 public hashdecl RestRequestServerInfo {
129 string path;
131 *hash<auto> query;
133 *hash<auto> path_args;
135 auto body;
137 hash<auto> info;
138 };
139
141 public hashdecl RestResponseClientInfo {
143 int code;
145 auto body;
147 hash<auto> hdr;
149 hash<auto> info;
150 };
151
153 public hashdecl RestExampleRequestInfo {
157 hash<auto> hdr;
159 string body;
160 };
161
163 public hashdecl RestExampleResponseInfo {
167 int code;
169 hash<auto> hdr;
171 string body;
172 };
173
175 public hashdecl RestQoreExampleCodeInfo {
177 hash<string, string> hashdecls();
178
180 string example;
181 };
182
185
186public:
187protected:
188 *Logger::Logger logger;
189
190public:
191
194
195
198
199
202
203
205
209 string getHash();
210
211
213
217 string getTargetUrl();
218
219
221
231 hash<RestRequestClientInfo> processRequest(string method, string path, auto body, *hash<auto> headers,
232 *softlist<string> content_types) {
233 return processRequestImpl(method, path, body, headers, content_types);
234 }
235
237
252 hash<RestRequestServerInfo> parseRequest(string method, string path, *data http_body,
253 reference<hash<auto>> headers) {
254 return parseRequestImpl(method, path, http_body, \headers);
255 }
256
258
280 hash<HttpResponseInfo> processResponse(string method, string path, int code, auto response_body,
281 *hash<auto> headers, *softlist<string> content_types) {
282 return processResponseImpl(method, path, code, response_body, headers, content_types);
283 }
284
286
294 hash<RestResponseClientInfo> parseResponse(string method, string path, int code, *data response_body,
295 hash<auto> hdr) {
296 // strip any query arguments from the path when validating
297 path =~ s/\?.*//;
298 return parseResponseImpl(method, path, code, response_body, hdr);
299 }
300
302
307 hash<RestQoreExampleCodeInfo> getQoreExampleRequest(string method, string path);
308
309
311
317 hash<RestExampleRequestInfo> getExampleRequest(string method, string path, *softlist<string> content_types);
318
319
321
327 hash<RestQoreExampleCodeInfo> getQoreExampleResponse(string method, string path, int code);
328
329
331
338 hash<RestExampleResponseInfo> getExampleResponse(string method, string path, int code,
339 *softlist<string> content_types) {
340 hash<RestExampleResponseInfo> rv = getExampleResponseImpl(method, path, code, content_types);
341 if (!rv.response_uri)
342 rv.response_uri = sprintf("HTTP/1.1 %d %s", code, HttpCodes{code} ?? "Unknown");
343 return rv;
344 }
345
347
349 hash<string, list<string>> getPathOperationHash();
350
351
353
355 string getBasePath();
356
357
359
361 setBasePath(string basePath);
362
363
365
374 DataProvider::AbstractDataProvider getDataProvider(HTTPClient rest);
375
376
378
381
382
384
388 setTimeZoneLocale(*TimeZone tz);
389
390
392
396 *TimeZone getTimeZoneLocale();
397
398
400
409protected:
410 DataProvider::AbstractDataProvider getDataProviderImpl(HTTPClient rest);
411public:
412
413
415
419protected:
420 abstract string getHashImpl();
421public:
422
424
428protected:
429 abstract string getTargetUrlImpl();
430public:
431
433
443 private abstract hash<RestRequestClientInfo> processRequestImpl(string method, string path, auto body,
444 *hash<auto> headers, *softlist<string> content_types);
445
447
458 private abstract hash<RestRequestServerInfo> parseRequestImpl(string method, string path, *data http_body,
459 reference<hash> headers);
460
462
477 private abstract hash<HttpResponseInfo> processResponseImpl(string method, string path, int code,
478 auto response_body, *hash<auto> headers, *softlist<string> content_types);
479
481
489 private abstract hash<RestResponseClientInfo> parseResponseImpl(string method, string path, int code,
490 *data response_body, hash<auto> hdr);
491
493
495protected:
496 abstract hash<string, list<string>> getPathOperationHashImpl();
497public:
498
500
502protected:
503 abstract string getBasePathImpl();
504public:
505
507
509protected:
510 abstract setBasePathImpl(string basePath);
511public:
512
514
519protected:
520 abstract hash<RestQoreExampleCodeInfo> getQoreExampleRequestImpl(string method, string path);
521public:
522
524
530 private abstract hash<RestExampleRequestInfo> getExampleRequestImpl(string method, string path,
531 *softlist<string> content_types);
532
534
540 private abstract hash<RestQoreExampleCodeInfo> getQoreExampleResponseImpl(string method, string path,
541 int code);
542
544
551 private abstract hash<RestExampleResponseInfo> getExampleResponseImpl(string method, string path, int code,
552 *softlist<string> content_types);
553
555
559protected:
560 abstract setTimeZoneLocaleImpl(*TimeZone tz);
561public:
562
564
568protected:
569 abstract *TimeZone getTimeZoneLocaleImpl();
570public:
571 };
572
575
576public:
579%ifndef NoJson
580 MimeTypeJson: \make_json(),
581%endif
582%ifndef NoYaml
583 MimeTypeYamlRpc: \make_yaml(),
584 MimeTypeYaml: \make_yaml(),
585%endif
586%ifndef NoXml
587 MimeTypeXml: \make_xmlrpc_value(),
588 MimeTypeXmlApp: string sub (auto v) {
589 switch (v.typeCode()) {
590 case NT_LIST: return make_xml(("list": ("element": v)));
591 case NT_HASH: return v.size() == 1 && v.firstValue().lsize() == 1 ? make_xml(v) : make_xml(("value": v));
592 }
593 return make_xml(("value": v));
594 },
595%endif
596 MimeTypeFormUrlEncoded: string sub (auto v) {
597 if (v.typeCode() == NT_HASH)
598 return mime_get_form_urlencoded_string(v);
599 throw "FORMURLENCODING-ERROR", sprintf("form URL encoding can only encode hashes; type %y requested", v.type());
600 },
601 MimeTypeText: data sub (auto s) {
602 switch (s.typeCode()) {
603 case NT_STRING:
604 case NT_BINARY:
605 return s;
606 default:
607 // issue #3547: send as a YAML-serialized string if possible to catch unserializable data
608%ifndef NoYaml
609 return make_yaml(s);
610%else
611 throw "TEXT-SERIALIZATION-ERROR", sprintf("cannot serialize type %y without YAML support", s.type());
612%endif
613 }
614 },
615 MimeTypeOctetStream: binary sub (auto s) {
616 switch (s.typeCode()) {
617 case NT_STRING:
618 return binary(s);
619 case NT_BINARY:
620 return s;
621 default:
622 # issue #3547: send as a YAML-serialized string if possible to catch unserializable data
623%ifndef NoYaml
624 return binary(make_yaml(s));
625%else
626 throw "BINARY-SERIALIZATION-ERROR", sprintf("cannot serialize type %y without YAML support", s.type());
627%endif
628 }
629 },
630 };
631
632 const DataSerializationSupportList = keys DataSerializationSupport;
633
634 const DeserializeYaml = ...;
635
636 const DeserializeXml = ...;
637
638
641 MimeTypeFormUrlEncoded: (
642 "code": "url",
643 "in": \mime_parse_form_urlencoded_string(),
644 ),
645%ifndef NoJson
646 MimeTypeJson: (
647 "code": "json",
648 "in": \parse_json(),
649 ),
650%endif
651%ifndef NoYaml
652 MimeTypeYamlRpc: DeserializeYaml,
653 MimeTypeYaml: DeserializeYaml,
654%endif
655%ifndef NoXml
656 MimeTypeXml: DeserializeXml,
657 MimeTypeXmlApp: DeserializeXml,
658%endif
659 MimeTypeText: (
660 "code": "text",
661 "in": data sub (data s) { return s; },
662 ),
663
664 MimeTypeOctetStream: {
665 "code": "bin",
666 "in": binary sub (data s) {
667 return s.typeCode() == NT_BINARY ? s : binary(s);
668 },
669 },
670 };
671
673
675 const NullSchemaHashStr = "<null rest schema>";
676
678
681
682
684
688protected:
689 string getHashImpl();
690public:
691
692
694
698protected:
700public:
701
702
704
714protected:
715 hash<RestRequestClientInfo> processRequestImpl(string method, string path, auto body, *hash<auto> headers, *softlist<string> content_types);
716public:
717
718
720
731protected:
732 hash<RestRequestServerInfo> parseRequestImpl(string method, string path, *data http_body, reference<hash> headers);
733public:
734
735
737
760 private hash<HttpResponseInfo> processResponseImpl(string method, string path, int code, auto response_body,
761 *hash<auto> headers, *softlist<string> content_types) {
762 hash<HttpResponseInfo> rv((
763 "code": code,
764 "hdr": headers,
765 ));
766
767 if (exists response_body);
768
769
770 rv.body = response_body;
771 rv.hdr = headers;
772 return rv;
773 }
774
776
784 private hash<RestResponseClientInfo> parseResponseImpl(string method, string path, int code,
785 *data response_body, hash<auto> hdr) {
786 hash<RestResponseClientInfo> rv((
787 "code": code,
788 "hdr": hdr,
789 ));
790
791 if (response_body.val());
792
793
794 return rv;
795 }
796
798
807 private:internal bool checkResponseContentTypeHeader(reference<hash<HttpResponseInfo>> resp, auto body,
808 *hash<auto> headers, *softlist<string> content_types) {
809 // quickly return if body is not in data format
810 if (body.typeCode() != NT_BINARY && body.typeCode() != NT_STRING)
811 return False;
812
813 // try to find \c Content-Type header
814 *list ct = map $1, keys headers, $1 ==1i;
815
816 // if found and it is accepted, use it and don't serialize the body
817 if (ct && ct.size() == 1);
818
819 return False;
820 }
821
823
825protected:
826 hash<string, list<string>> getPathOperationHashImpl();
827public:
828
829
831
833protected:
835public:
836
837
839
841protected:
842 setBasePathImpl(string basePath);
843public:
844
845
847
852protected:
853 hash<RestQoreExampleCodeInfo> getQoreExampleRequestImpl(string method, string path);
854public:
855
856
858
864 private hash<RestExampleRequestInfo> getExampleRequestImpl(string method, string path,
865 *softlist<string> content_types) {
866 return new hash<RestExampleRequestInfo>();
867 }
868
870
876protected:
877 hash<RestQoreExampleCodeInfo> getQoreExampleResponseImpl(string method, string path, int code);
878public:
879
880
882
889 private hash<RestExampleResponseInfo> getExampleResponseImpl(string method, string path, int code,
890 *softlist<string> content_types) {
891 return new hash<RestExampleResponseInfo>();
892 }
893
895
899protected:
901public:
902
903
905
909protected:
911public:
912
913 };
914};
abstract REST schema validation classes
Definition: RestSchemaValidator.qm.dox.h:184
bool managesUriPath()
returns True if the provider manages the URI path
abstract private hash< RestRequestClientInfo > processRequestImpl(string method, string path, auto body, *hash< auto > headers, *softlist< string > content_types)
processes a client-side REST request and returns a hash that can be used to make the outgoing client-...
hash< RestRequestClientInfo > processRequest(string method, string path, auto body, *hash< auto > headers, *softlist< string > content_types)
processes a client-side REST request and returns a hash that can be used to make the outgoing client-...
Definition: RestSchemaValidator.qm.dox.h:231
abstract private hash< RestExampleRequestInfo > getExampleRequestImpl(string method, string path, *softlist< string > content_types)
returns a hash of example message information for the given request
hash< RestExampleRequestInfo > getExampleRequest(string method, string path, *softlist< string > content_types)
returns a hash of example message information for the given request
*TimeZone getTimeZoneLocale()
Returns the time zone locale used for serialization / deserialization.
DataProvider::AbstractDataProvider getDataProviderImpl(HTTPClient rest)
returns a data provider object for this connection, if supported by any REST schema validator object
string getTargetUrl()
returns the target URL for the schema
abstract private hash< RestQoreExampleCodeInfo > getQoreExampleResponseImpl(string method, string path, int code)
returns example Qore code for the given response
abstract private hash< RestResponseClientInfo > parseResponseImpl(string method, string path, int code, *data response_body, hash< auto > hdr)
parses and validates the response from the server and returns a hash of the processed info
abstract string getHashImpl()
returns a unique hash for the schema that can be used to compare schemas
hash< RestQoreExampleCodeInfo > getQoreExampleRequest(string method, string path)
returns a hash of example Qore code for the given request
abstract setBasePathImpl(string basePath)
overrides the basePath value
hash< RestQoreExampleCodeInfo > getQoreExampleResponse(string method, string path, int code)
returns example Qore code for the given response
abstract setTimeZoneLocaleImpl(*TimeZone tz)
Allows the time zone locale to be set for serialization / deserialization.
constructor(Logger::Logger logger)
Creates the object with the given logger.
abstract string getTargetUrlImpl()
returns the target URL for the schema
abstract *TimeZone getTimeZoneLocaleImpl()
Returns the time zone locale used for serialization / deserialization.
constructor()
Creates the object without a logger.
abstract hash< string, list< string > > getPathOperationHashImpl()
returns a hash of URI paths as keys with values as lists of supported HTTP methods
hash< RestRequestServerInfo > parseRequest(string method, string path, *data http_body, reference< hash< auto > > headers)
processes and parses a client request and returns the deserialized message body (if any)
Definition: RestSchemaValidator.qm.dox.h:252
abstract string getBasePathImpl()
returns the base path prefix for all requests in this schema
hash< HttpResponseInfo > processResponse(string method, string path, int code, auto response_body, *hash< auto > headers, *softlist< string > content_types)
Processes a REST response with a serialized message body.
Definition: RestSchemaValidator.qm.dox.h:280
setLogger(Logger::Logger logger)
Sets a new logger.
setTimeZoneLocale(*TimeZone tz)
Allows the time zone locale to be set for serialization / deserialization.
abstract private hash< RestExampleResponseInfo > getExampleResponseImpl(string method, string path, int code, *softlist< string > content_types)
returns a hash of example message information for the given request
string getHash()
returns a unique hash for the schema that can be used to compare schemas
DataProvider::AbstractDataProvider getDataProvider(HTTPClient rest)
returns a data provider object for this connection, if supported by any REST schema validator object
abstract private hash< HttpResponseInfo > processResponseImpl(string method, string path, int code, auto response_body, *hash< auto > headers, *softlist< string > content_types)
processes a REST response with a serialized message body, validates any response data against schema ...
hash< string, list< string > > getPathOperationHash()
returns a hash of URI paths as keys with values as lists of supported HTTP methods
hash< RestResponseClientInfo > parseResponse(string method, string path, int code, *data response_body, hash< auto > hdr)
parses and validates the response from the server and returns a hash of the processed info
Definition: RestSchemaValidator.qm.dox.h:294
abstract private hash< RestRequestServerInfo > parseRequestImpl(string method, string path, *data http_body, reference< hash > headers)
processes and parses a client request and returns the deserialized message body (if any)
string getBasePath()
returns the base path prefix for all requests in this schema
abstract hash< RestQoreExampleCodeInfo > getQoreExampleRequestImpl(string method, string path)
returns a hash of example Qore code for the given request
hash< RestExampleResponseInfo > getExampleResponse(string method, string path, int code, *softlist< string > content_types)
returns a hash of example message information for the given request
Definition: RestSchemaValidator.qm.dox.h:338
setBasePath(string basePath)
overrides the basePath value
null REST validator; no schema is used but default serialization and deserialization is performed
Definition: RestSchemaValidator.qm.dox.h:574
setBasePathImpl(string basePath)
overrides the basePath value
string getHashImpl()
returns a unique hash for the schema that can be used to compare schemas
const DataDeserializationSupport
Data deserialization support MIME types to codes and de/serialization functions.
Definition: RestSchemaValidator.qm.dox.h:640
private hash< RestResponseClientInfo > parseResponseImpl(string method, string path, int code, *data response_body, hash< auto > hdr)
parses and validates the response from the server and returns a hash of the processed info
Definition: RestSchemaValidator.qm.dox.h:784
const DataSerializationSupport
Data serialization support mapping codes to MIME types and de/serialization functions.
Definition: RestSchemaValidator.qm.dox.h:578
*TimeZone getTimeZoneLocaleImpl()
Returns the time zone locale used for serialization / deserialization.
hash< RestRequestClientInfo > processRequestImpl(string method, string path, auto body, *hash< auto > headers, *softlist< string > content_types)
processes a client-side REST request and returns a hash that can be used to make the outgoing client-...
const NullSchemaHashStr
a unique hash for the null schema
Definition: RestSchemaValidator.qm.dox.h:675
setTimeZoneLocaleImpl(*TimeZone tz)
Allows the time zone locale to be set for serialization / deserialization.
string getTargetUrlImpl()
returns the target URL for the schema
bool managesUriPath()
returns True if the provider manages the URI path
hash< RestQoreExampleCodeInfo > getQoreExampleResponseImpl(string method, string path, int code)
returns example Qore code for the given response
hash< RestQoreExampleCodeInfo > getQoreExampleRequestImpl(string method, string path)
returns a hash of example Qore code for the given request
private hash< RestExampleResponseInfo > getExampleResponseImpl(string method, string path, int code, *softlist< string > content_types)
returns a hash of example message information for the given request
Definition: RestSchemaValidator.qm.dox.h:889
hash< RestRequestServerInfo > parseRequestImpl(string method, string path, *data http_body, reference< hash > headers)
processes and parses a client request and returns the deserialized message body (if any)
internal bool checkResponseContentTypeHeader(reference< hash< HttpResponseInfo > > resp, auto body, *hash< auto > headers, *softlist< string > content_types)
Check if the headers contain a content-type header which is accepted and if so, modify the response h...
Definition: RestSchemaValidator.qm.dox.h:807
string getBasePathImpl()
returns the base path prefix for all requests in this schema
hash< string, list< string > > getPathOperationHashImpl()
returns a hash of URI paths as keys with values as lists of supported HTTP methods
private hash< HttpResponseInfo > processResponseImpl(string method, string path, int code, auto response_body, *hash< auto > headers, *softlist< string > content_types)
processes a REST response with a serialized message body, validates any response data against schema ...
Definition: RestSchemaValidator.qm.dox.h:760
private hash< RestExampleRequestInfo > getExampleRequestImpl(string method, string path, *softlist< string > content_types)
returns a hash of example message information for the given request
Definition: RestSchemaValidator.qm.dox.h:864
main namespace for all public RestSchemaValidator declarations
Definition: RestSchemaValidator.qm.dox.h:111
a hash giving example info for example HTTP request messages
Definition: RestSchemaValidator.qm.dox.h:153
string body
the HTTP request body
Definition: RestSchemaValidator.qm.dox.h:159
hash< auto > hdr
the HTTP request header hash
Definition: RestSchemaValidator.qm.dox.h:157
string request_uri
the HTTP request URI
Definition: RestSchemaValidator.qm.dox.h:155
a hash giving example info for example HTTP response messages
Definition: RestSchemaValidator.qm.dox.h:163
int code
the HTTP status code
Definition: RestSchemaValidator.qm.dox.h:167
string response_uri
the HTTP response URI
Definition: RestSchemaValidator.qm.dox.h:165
string body
the HTTP response body
Definition: RestSchemaValidator.qm.dox.h:171
hash< auto > hdr
the HTTP response header hash
Definition: RestSchemaValidator.qm.dox.h:169
a hash giving example information for building a request or response in Qore
Definition: RestSchemaValidator.qm.dox.h:175
string example
a string giving the example code generation
Definition: RestSchemaValidator.qm.dox.h:180
hash< string, string > hashdecls()
a hash giving example hashdecl declarations for hash objects in the message; keys are hashdecl names; str...
a hash of information about a client-side request
Definition: RestSchemaValidator.qm.dox.h:113
*list< string > response_content
Content-Type for the response message if available.
Definition: RestSchemaValidator.qm.dox.h:121
*data body
the serialized message body hash
Definition: RestSchemaValidator.qm.dox.h:123
string content
the Content-Type for the message
Definition: RestSchemaValidator.qm.dox.h:117
string uri_path
the URI path for the request
Definition: RestSchemaValidator.qm.dox.h:115
a hash of information about a server-side request
Definition: RestSchemaValidator.qm.dox.h:127
*hash< auto > path_args
any path arguments
Definition: RestSchemaValidator.qm.dox.h:133
hash< auto > info
miscellaneous free-form info about the parsed request
Definition: RestSchemaValidator.qm.dox.h:137
string path
the URI path without query arguments
Definition: RestSchemaValidator.qm.dox.h:129
*hash< auto > query
any query arguments
Definition: RestSchemaValidator.qm.dox.h:131
auto body
the deserialized message body data
Definition: RestSchemaValidator.qm.dox.h:135
a hash of information about a response from the server
Definition: RestSchemaValidator.qm.dox.h:141
hash< auto > hdr
the HTTP headers received
Definition: RestSchemaValidator.qm.dox.h:147
int code
the HTTP status code
Definition: RestSchemaValidator.qm.dox.h:143
hash< auto > info
miscellaneous free-form info about the parsed response
Definition: RestSchemaValidator.qm.dox.h:149
auto body
the deserialized message body
Definition: RestSchemaValidator.qm.dox.h:145