Skip to content

Commit 1528945

Browse files
authored
fix: Set application/json by default when using json structured format (#59)
Signed-off-by: Daniel Azuma <[email protected]>
1 parent 71f0ea8 commit 1528945

File tree

6 files changed

+504
-429
lines changed

6 files changed

+504
-429
lines changed

lib/cloud_events/errors.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ class AttributeError < CloudEventsError
5454
##
5555
# Alias of UnsupportedFormatError, for backward compatibility.
5656
#
57-
# @deprecated Will be removed in version 1.0.
58-
# @private
57+
# @deprecated Will be removed in version 1.0. Use {UnsupportedFormatError}.
5958
#
6059
HttpContentError = UnsupportedFormatError
6160
end

lib/cloud_events/format.rb

Lines changed: 168 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -8,162 +8,194 @@ module CloudEvents
88
# This module documents the method signatures that may be implemented by
99
# formatters.
1010
#
11-
# Note that a formatter need not implement all methods. For example, an event
12-
# formatter should implement `decode_event` and `encode_event`, and may also
13-
# implement `decode_batch` and `encode_batch`, but might not implement
14-
# `decode_data` or `encode_data`. Additionally, this module itself is present
15-
# primarily for documentation, and need not be directly included by
16-
# implementations.
11+
# A formatter is an object that implenets "structured" event encoding and
12+
# decoding strategies for a particular format (such as JSON). In general,
13+
# this includes four operations:
14+
#
15+
# * Decoding an entire event or batch of events from a input source.
16+
# This is implemented by the {Format#decode_event} method.
17+
# * Encoding an entire event or batch of events to an output sink.
18+
# This is implemented by the {Format#encode_event} method.
19+
# * Decoding an event payload (i.e. the `data` attribute) Ruby object from a
20+
# serialized representation.
21+
# This is implemented by the {Format#decode_data} method.
22+
# * Encoding an event payload (i.e. the `data` attribute) Ruby object to a
23+
# serialized representation.
24+
# This is implemented by the {Format#encode_data} method.
25+
#
26+
# Each method takes a set of keyword arguments, and returns either a `Hash`
27+
# or `nil`. A Hash indicates that the formatter understands the request and
28+
# is returning its response. A return value of `nil` means the formatter does
29+
# not understand the request and is declining to perform the operation. In
30+
# such a case, it is possible that a different formatter should handle it.
31+
#
32+
# Both the keyword arguments recognized and the returned hash members may
33+
# vary from formatter to formatter; similarly, the keyword arguments provided
34+
# and the resturned hash members recognized may also vary for different
35+
# callers. This interface will define a set of common argument and result key
36+
# names, but both callers and formatters must gracefully handle the case of
37+
# missing or extra information. For example, if a formatter expects a certain
38+
# argument but does not receive it, it can assume the caller does not have
39+
# the required information, and it may respond by returning `nil` to decline
40+
# the request. Similarly, if a caller expects a response key but does not
41+
# receive it, it can assume the formatter does not provide it, and it may
42+
# respond by trying a different formatter.
43+
#
44+
# Additionally, any particular formatter need not implement all methods. For
45+
# example, an event formatter would generally implement {Format#decode_event}
46+
# and {Format#encode_event}, but might not implement {Format#decode_data} or
47+
# {Format#encode_data}.
48+
#
49+
# Finally, this module itself is present primarily for documentation, and
50+
# need not be directly included by formatter implementations.
1751
#
1852
module Format
1953
##
20-
# Decode an event from the given serialized input.
21-
#
22-
# The arguments comprise an input string representing the encoded event
23-
# from a protocol source such as an HTTP request body, and a ContentType.
24-
# All additional arguments are optional, and may or may not be considered
25-
# by the formatter.
26-
#
27-
# The formatter must return either an event object, or `nil` to signal that
28-
# the formatter does not recognize the input and believes it should be
29-
# handled by a different formatter.
30-
# It can also raise an error to indicate that it believes it should handle
31-
# the input, but that the data is malformed.
32-
#
33-
# @param input [String] The input as a string.
34-
# @param content_type [CloudEvents::ContentType,nil] The input content
35-
# type, or `nil` if none is available.
36-
# @return [CloudEvents::Event] if decoding succeeded.
37-
# @return [nil] if a different formatter should be used.
38-
#
39-
def decode_event input, content_type, **_other_kwargs
40-
nil
41-
end
42-
43-
##
44-
# Encode an event to a string.
54+
# Decode an event or batch from the given serialized input. This is
55+
# typically called by a protocol binding to deserialize event data from an
56+
# input stream.
4557
#
46-
# The input must be a CloudEvent object. All additional arguments are
47-
# optional, and may or may not be considered by the formatter.
58+
# Common arguments include:
4859
#
49-
# The formatter must return either a tuple comprising the serialized form
50-
# of the event and an associated ContentType, or `nil` to signal that the
51-
# formatter is incapable of handling the given event and believes it should
52-
# be handled by a different formatter.
53-
# It can also raise an error to indicate that it believes it should handle
54-
# the input, but that the input is malformed.
60+
# * `:content` (String) Serialized content to decode. For example, it could
61+
# be from an HTTP request body.
62+
# * `:content_type` ({CloudEvents::ContentType}) The content type. For
63+
# example, it could be from the `Content-Type` header of an HTTP request.
5564
#
56-
# Implementations should make sure the encoding of the returned string is
57-
# correct. In particular, if the format uses binary data, the returned
58-
# string should have the appropriate `ASCII_8BIT` encoding, and the
59-
# returned ContentType should specify the appropriate charset.
65+
# The formatter must first determine whether it is able to interpret the
66+
# given input. Typically, this is done by inspecting the `content_type`.
67+
# If the formatter determines that it is unable to interpret the input, it
68+
# should return `nil`. Otherwise, if the formatter determines it can decode
69+
# the input, it should return a `Hash`. Common hash keys include:
6070
#
61-
# @param event [CloudEvents::Event] The input event.
62-
# @return [Array(String,CloudEvents::ContentType)] if encoding succeeded.
63-
# @return [nil] if a different formatter should be used.
71+
# * `:event` ({CloudEvents::Event}) A single event decoded from the input.
72+
# * `:event_batch` (Array of {CloudEvents::Event}) A batch of events
73+
# decoded from the input.
6474
#
65-
def encode_event event, **_other_kwargs
66-
nil
67-
end
68-
69-
##
70-
# Decode a batch of events from the given serialized input.
71-
#
72-
# The arguments comprise an input string representing the encoded batch of
73-
# events from a protocol source such as an HTTP request body, and a
74-
# ContentType. All additional arguments are optional, and may or may not be
75-
# considered by the formatter.
76-
#
77-
# The formatter must return either an array (possibly empty) of event
78-
# objects, or `nil` to signal that the formatter does not recognize the
79-
# input and believes it should be handled by a different formatter.
80-
# It can also raise an error to indicate that it believes it should handle
81-
# the input, but that the data is malformed.
82-
#
83-
# @param input [String] The input as a string.
84-
# @param content_type [CloudEvents::ContentType,nil] The input content
85-
# type, or `nil` if none is available.
86-
# @return [Array<CloudEvents::Event>] if decoding succeeded.
87-
# @return [nil] if a different formatter should be used.
88-
#
89-
def decode_batch input, content_type, **_other_kwargs
75+
# The formatter may also raise a {CloudEvents::CloudEventsError} subclass
76+
# if it understood the request but determines that the input source is
77+
# malformed.
78+
#
79+
# @param _kwargs [keywords] Arguments
80+
# @return [Hash] if accepting the request and returning a result
81+
# @return [nil] if declining the request.
82+
#
83+
def decode_event **_kwargs
9084
nil
9185
end
9286

9387
##
94-
# Encode a batch of events to a string.
95-
#
96-
# The input must be an array of CloudEvent objects (which could be empty).
97-
# All additional arguments are optional, and may or may not be considered
98-
# by the formatter.
99-
#
100-
# The formatter must return either a tuple comprising the serialized form
101-
# of the batch and an associated ContentType, or `nil` to signal that the
102-
# formatter is incapable of handling the given batch and believes it should
103-
# be handled by a different formatter.
104-
# It can also raise an error to indicate that it believes it should handle
105-
# the input, but that the input is malformed.
106-
#
107-
# Implementations should make sure the encoding of the returned string is
108-
# correct. In particular, if the format uses binary data, the returned
109-
# string should have the appropriate `ASCII_8BIT` encoding, and the
110-
# returned ContentType should specify the appropriate charset.
111-
#
112-
# @param events [Array<CloudEvents::Event>] An array of input events.
113-
# @return [Array(String,CloudEvents::ContentType)] if encoding succeeded.
114-
# @return [nil] if a different formatter should be used.
115-
#
116-
def encode_batch events, **_other_kwargs
88+
# Encode an event or batch to a string. This is typically called by a
89+
# protocol binding to serialize event data to an output stream.
90+
#
91+
# Common arguments include:
92+
#
93+
# * `:event` ({CloudEvents::Event}) A single event to encode.
94+
# * `:event_batch` (Array of {CloudEvents::Event}) A batch of events to
95+
# encode.
96+
#
97+
# The formatter must first determine whether it is able to interpret the
98+
# given input. Typically, most formatters should be able to handle any
99+
# event or event batch, but a specialized formatter that can handle only
100+
# certain kinds of events may return `nil` to decline unwanted inputs.
101+
# Otherwise, if the formatter determines it can encode the input, it should
102+
# return a `Hash`. common hash keys include:
103+
#
104+
# * `:content` (String) The serialized form of the event. This might, for
105+
# example, be written to an HTTP request body. Care should be taken to
106+
# set the string's encoding properly. In particular, to output binary
107+
# data, the encoding should probably be set to `ASCII_8BIT`.
108+
# * `:content_type` ({CloudEvents::ContentType}) The content type for the
109+
# output. This might, for example, be written to the `Content-Type`
110+
# header of an HTTP request.
111+
#
112+
# The formatter may also raise a {CloudEvents::CloudEventsError} subclass
113+
# if it understood the request but determines that the input source is
114+
# malformed.
115+
#
116+
# @param _kwargs [keywords] Arguments
117+
# @return [Hash] if accepting the request and returning a result
118+
# @return [nil] if declining the request.
119+
#
120+
def encode_event **_kwargs
117121
nil
118122
end
119123

120124
##
121-
# Decode an event data object from string format.
122-
#
123-
# The arguments comprise an input string representing the encoded data from
124-
# a protocol source such as an HTTP request body, and a ContentType. All
125-
# additional arguments are optional, and may or may not be considered by
126-
# the formatter.
127-
#
128-
# The formatter must return either a tuple comprising the event data object
129-
# and a final ContentType (which may be the same as the input ContentType),
130-
# or `nil` to signal that the formatter does not recognize the input and
131-
# believes it should be handled by a different formatter.
132-
# It can also raise an error to indicate that it believes it should handle
133-
# the input, but that the input is malformed.
134-
#
135-
# @param data [String] The input data string.
136-
# @param content_type [CloudEvents::ContentType,nil] The input content
137-
# type, or `nil` if none is available.
138-
# @return [Array(Object,CloudEvents::ContentType)] if decoding succeeded.
139-
# @return [nil] if a different formatter should be used.
140-
#
141-
def decode_data data, content_type, **_other_kwargs
125+
# Decode an event data object from string format. This is typically called
126+
# by a protocol binding to deserialize the payload (i.e. `data` attribute)
127+
# of an event as part of "binary content mode" decoding.
128+
#
129+
# Common arguments include:
130+
#
131+
# * `:spec_version` (String) The `specversion` of the event.
132+
# * `:content` (String) Serialized payload to decode. For example, it could
133+
# be from an HTTP request body.
134+
# * `:content_type` ({CloudEvents::ContentType}) The content type. For
135+
# example, it could be from the `Content-Type` header of an HTTP request.
136+
#
137+
# The formatter must first determine whether it is able to interpret the
138+
# given input. Typically, this is done by inspecting the `content_type`.
139+
# If the formatter determines that it is unable to interpret the input, it
140+
# should return `nil`. Otherwise, if the formatter determines it can decode
141+
# the input, it should return a `Hash`. Common hash keys include:
142+
#
143+
# * `:data` (Object) The payload object to be set as the `data` attribute
144+
# in a {CloudEvents::Event} object.
145+
# * `:content_type` ({CloudEvents::ContentType}) The content type to be set
146+
# as the `datacontenttype` attribute in a {CloudEvents::Event} object.
147+
# In many cases, this may simply be copied from the `:content_type`
148+
# argument, but a formatter could modify it to provide corrections or
149+
# additional information.
150+
#
151+
# The formatter may also raise a {CloudEvents::CloudEventsError} subclass
152+
# if it understood the request but determines that the input source is
153+
# malformed.
154+
#
155+
# @param _kwargs [keywords] Arguments
156+
# @return [Hash] if accepting the request and returning a result
157+
# @return [nil] if declining the request.
158+
#
159+
def decode_data **_kwargs
142160
nil
143161
end
144162

145163
##
146-
# Encode an event data object to string format.
147-
#
148-
# The arguments comprise an object representing the event data, and a
149-
# suggested ContentType. All additional arguments are optional, and may or
150-
# may not be considered by the formatter.
151-
#
152-
# The formatter must return either a tuple comprising the encoded data
153-
# string and a final ContentType (which may be the same as the input
154-
# ContentType), or `nil` to signal that the formatter is incapable of
155-
# handling the given data object and believes it should be handled by a
156-
# different formatter.
157-
# It can also raise an error to indicate that it believes it should handle
158-
# the input, but that the input is malformed.
159-
#
160-
# @param data [Object] A data object to encode.
161-
# @param content_type [CloudEvents::ContentType,nil] The input content
162-
# type, or `nil` if none is available.
163-
# @return [Array(String,CloudEvents::ContentType)] if encoding succeeded.
164-
# @return [nil] if a different formatter should be used.
165-
#
166-
def encode_data data, content_type, **_other_kwargs
164+
# Encode an event data object to string format. This is typically called by
165+
# a protocol binding to serialize the payload (i.e. `data` attribute and
166+
# corresponding `datacontenttype` attribute) of an event as part of "binary
167+
# content mode" encoding.
168+
#
169+
# Common arguments include:
170+
#
171+
# * `:spec_version` (String) The `specversion` of the event.
172+
# * `:data` (Object) The payload object from an event's `data` attribute.
173+
# * `:content_type` ({CloudEvents::ContentType}) The content type from an
174+
# event's `datacontenttype` attribute.
175+
#
176+
# The formatter must first determine whether it is able to interpret the
177+
# given input. Typically, this is done by inspecting the `content_type`.
178+
# If the formatter determines that it is unable to interpret the input, it
179+
# should return `nil`. Otherwise, if the formatter determines it can decode
180+
# the input, it should return a `Hash`. Common hash keys include:
181+
#
182+
# * `:content` (String) The serialized form of the data. This might, for
183+
# example, be written to an HTTP request body. Care should be taken to
184+
# set the string's encoding properly. In particular, to output binary
185+
# data, the encoding should probably be set to `ASCII_8BIT`.
186+
# * `:content_type` ({CloudEvents::ContentType}) The content type for the
187+
# output. This might, for example, be written to the `Content-Type`
188+
# header of an HTTP request.
189+
#
190+
# The formatter may also raise a {CloudEvents::CloudEventsError} subclass
191+
# if it understood the request but determines that the input source is
192+
# malformed.
193+
#
194+
# @param _kwargs [keywords] Arguments
195+
# @return [Hash] if accepting the request and returning a result
196+
# @return [nil] if declining the request.
197+
#
198+
def encode_data **_kwargs
167199
nil
168200
end
169201
end

0 commit comments

Comments
 (0)