Lenses are definitely not necessary to do what you want here. In haskell, you typically keep the JSON data to the very periphery of your program.
You would probably have some Request with a ToJSON instance and Token types such as:
data Request = Request
{ url :: URI
, method :: Method
, headers :: [Header]
, body :: ByteString
...
}
instance ToJSON Request where
toJSON = ...
newtype Token = Token ByteString
Then you might write a function to add the token header:
applyAuthToken :: Token -> Request -> Request
applyAuthToken (Token tok) req = req { headers = ("token", tok) : req headers }
Or if you really wanted to use a lens you could do:
headersL :: Lens' Request [Header]
headersL = lens headers (\req hdrs -> req { headers = hdrs })
applyAuthToken :: Token -> Request -> Request
applyAuthToken (Token tok) req = over headersL ("token", tok) :) req
Then you call applyAuthToken right before serializing your Request type to a JSON ByteString.
edit: sorry I see that you wanted the auth token in the body not the headers. Its the exact same concept but you would make the `body` field in `Request` into some other specific type with a ToJSON instance and a slightly different `applyAuthToken` function.