-
Notifications
You must be signed in to change notification settings - Fork 19
/
json-request.lisp
58 lines (52 loc) · 1.94 KB
/
json-request.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
(defpackage #:aws-sdk/json-request
(:use #:cl)
(:import-from #:aws-sdk/request
#:request
#:request-payload
#:request-headers
#:request-operation)
(:import-from #:aws-sdk/session
#:*session*)
(:import-from #:trivial-types
#:property-list-p
#:association-list-p)
(:import-from #:yason)
(:import-from #:cl-base64)
(:export #:json-request))
(in-package #:aws-sdk/json-request)
(defclass json-request (request)
((json-version :initarg :json-version
:reader json-request-json-version)
(target-prefix :initarg :target-prefix
:reader json-request-target-prefix)))
(defmethod initialize-instance :after ((req json-request) &rest args &key params json-version target-prefix operation &allow-other-keys)
(declare (ignore args))
(setf (request-payload req) (to-json params))
(alexandria:appendf (request-headers req)
(list (cons "Content-Type"
(uiop:strcat "application/x-amz-json-" json-version)))
(when target-prefix
(list (cons "X-Amz-Target"
(format nil "~A.~A" target-prefix operation))))))
(defun %to-json (object)
(typecase object
(null
(yason:encode :null))
((satisfies association-list-p)
(yason:with-object ()
(loop for (key . val) in object
do (yason:with-object-element (key)
(%to-json val)))))
(list
(yason:with-array ()
(dolist (i object)
(yason:encode-array-element i))))
((and vector (not string))
(yason:encode (base64:usb8-array-to-base64-string object)))
(keyword
(let ((*print-case* :downcase))
(yason:encode (princ-to-string object))))
(t
(yason:encode object))))
(defun to-json (params)
(yason:with-output-to-string* () (%to-json params)))