Base64 type states that it represents URL encoded string but in JSON, it uses standard base64 encoding
jan-dubsky opened this issue · comments
I have just run into a weird behaviour of Base64 data type. The documentation comment of this type clearly states that this type represents base64 encoded data using URL encoding:
// Base64 represents a base64 encoded string, using URLEncoding alphabet
//
// swagger:strfmt byte
type Base64 []byte
Unfortunately the doc-comment is just partially true. It's true that the type uses URL encoding to implement TextMarshaler
and TextUnmarshaler
interfaces. But it's definitely not true for the rest of interfaces implemented. Namely JSON
and BSON
serialization and deserialization and also database interfaces sql.Scanner
and driver.Valuer
all of those use standard base64 encoding and not URL encoding as the doc-comment states.
This behaviour is inconsistent both with the type doc-comment, but it's also inconsistent behaviour of the type itself, as some methods use different encoding than others. I was able to track that this change has been implemented in #57 as a reaction to #56, but I was not able to find any explanation justifying this inconsistent behaviour.
I have observed this issue in my code which implements cursor-based pagination algorithm. I use type: string, format: byte
in my swagger specification (I use go-swagger v0.27.0
) for both request parameter and response field. The request cursor
parameter is a query parameter of a GET
HTTP call. The nextCursor
field is then returned as a JSON field. And here comes the problem. Even though the cursor
is supposed to be a perfectly opaque value for a client, in this case it's not because of the Base64
type inconsistency: In request query parameter, the Base64
type is decoded as URL encoded base64 string. So far so good. But the nextCursor
is sent as a JSON field and though the MarshalJSON
method is used. But this method encodes Base64
type as standard base64 encoding. Consequently, the client would have to read the nextCursor
value in standard base64 and re-encode it to URL base64 to be able to use the cursor
in the next API call. Which is quite far from the desired opaque token.
I'd like to ask whether this inconsistency of Base64
type is intended and if it is, I'd be interested in the reasoning behind. Alternatively, I'd love to discuss possible modifications of Base64
type which would unify the encoding used in all interfaces.