go-openapi / strfmt

openapi toolkit common string formats

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.