-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ability to add custom transformation/unpacking of embedded data #153
Comments
Hey @thedarkside, thanks for your thoughts! I've actually been having similar ideas. 😅 I started fiddling around with something in https://github.com/balvig/spyke/pull/137/files a while ago that I never quite got to wrap up. Could you take a look and see if it's something like that you had in mind? |
@balvig yes that would indeed make it simpler on my side because currenlty i still have a Faraday middleware in place just to rename Strapi's class FormatHandler < Faraday::Middleware
def on_complete(env)
env.body[:metadata] = env.body.delete(:meta)
end
end
def self.connection
@conn ||= Strapi::Client.conn do |builder|
builder.use FormatHandler
end
end I dont like this boilerplate either. Should be definitely easier to accomplish! But your idea isnt flexible enough i fear. For example it isnt sufficient if the data of interest is nested deeper (more then 1 levels). It also would not solve my problem outlined above either because the data of interest is nested deeper in the payload your solution wouldnt reach. I prefer to leave that flexibility to the users here by opening up a surface they can hook into if they want to. With inheritance this is really easy to do. So imho i would also implement a class StrapiBaseRecord < Spyke::Base
def self.unpack_base(payload)
payload[:metadata] = payload.delete(:meta)
payload
end
end In there you can do whatever you want. Adding, deleting, transforming whatever needs to be done to feed the data into Spyke. |
A working monkeypatch including now also the base unpacking mechanic. Ive borrowed the class Spyke::Result
def self.new_from_response_body(body)
new(body)
end
end
class Spyke::Base
# Allows customization via overriding. Per default returns payload untouched.
def self.unpack_base(payload) = payload
def self.unpack_embedded(payload) = payload
end
module Spyke::Http::ClassMethods
def request(method, path, params = {})
ActiveSupport::Notifications.instrument('request.spyke', method: method) do |payload|
response = send_request(method, path, params)
payload[:url], payload[:status] = response.env.url, response.status
::Spyke::Result.new_from_response_body(unpack_base response.body)
end
end
end
class Spyke::Associations::Association
private
def embedded_data
parent.class.unpack_embedded parent.attributes[name]
end
end |
Spyke expects data in the form of
But apis must not stick to this schema. For example strapi is encapsulating nested objects in a subsequent "data" object like this:
Currently the only way of making that Spyke-compatible is to hook into Faraday and transform the payload before it gets processed by Spyke.
But at this stage we have to iterate over the whole payload and guess. We can't easily rely on the associations configuration in our Spyke models.
A better approach would be to provide a way to change the processing of nested objects if necessary.
Ive created a patch as a poc:
With this in place i'am now able to override my
StrapiBaseRecord
to hook into the embedded processing and transform the payload to make it Spyke-compatible.What do you think?
Currently i am using Spyke just to consume payload. No writing involved at all. Therefor i'am not sure this approach is safe for all operations.
For my usecase it's working great!
The text was updated successfully, but these errors were encountered: