hakamadare / rubygem-surveymonkey

Ruby API client for SurveyMonkey
https://rubygems.org/gems/surveymonkey
MIT License
4 stars 3 forks source link

API Version 3 Support #6

Open ghost opened 8 years ago

ghost commented 8 years ago

I'd like to see what it would take to add support for the version 3 API while retaining backward compatibility (e.g. defaulting to version 2). If support were added, how do you see the user specifying which version to use? There are three reasonable (I think) approaches that I could come up with.

Option 1 - API version is derived from the methods themselves:

# Uses version 2
Surveymonkey.get_survey_list

# Users version 3
Surveymonkey.get_surveys

Option 2 - Use existing methods where applicable, and specify v3 using an additional option:

# Same call is used for both API versions
Surveymonkey.get_survey_list('version' => 3)

Option 3 - Use existing methods where applicable, and specify v3 by calling a scoped method before making API requests

# Specify API version
Surveymonkey::api_version(3)

# Will use version 3 API
Surveymonkey.get_survey_list

I'd love to hear some feedback - did you already have a plan for this?

hakamadare commented 8 years ago

@cescue those three ideas make sense to me. the first one seems susceptible to ambiguity, and i'd like to keep the Ruby method names as close as possible to the REST endpoint names. the third one is the closest to what i have in mind.

i do indeed have a plan, but it is not set in stone, and it would be great to get some feedback before i start implementing. the basic idea is to use the Surveymonkey::API namespace to hold any API-version-specific information, and ensure that Surveymonkey::Client is essentially an engine for passing requests into that namespace and presenting the responses to the end user. here is the hand-wavy outline:

  1. make :api_version an optional parameter passed to Surveymonkey::Client and Surveymonkey::API at initialization (immutable afterwards), default 2, also accepts 3, anything else invalid for now, reads from a class variable (which can be overridden by an environment variable)
  2. move the current Surveymonkey::API implementation into Surveymonkey::API::V2
  3. make Surveymonkey::API a lightweight wrapper around Surveymonkey::API::V2
  4. find all the places in the code where my abstraction falls down, curse past-@hakamadare, refactor
  5. build Surveymonkey::API::V3

so usage would look something like:

# V2 methods by default
Surveymonkey.get_surveys
#=> list of surveys

# V3 methods on demand
Surveymonkey::API::version = 3

Surveymonkey.surveys
#=> list of surveys
Surveymonkey.surveys(id: XXXXX, details: true)
#=> specific survey with details

or alternately

$ export SURVEYMONKEY_API_VERSION=3
Surveymonkey.surveys
#=> list of surveys
Surveymonkey.get_surveys
#=> some kind of exception, ideally with a message about invalid API version

thoughts?

also, i would LOVE help with this. given my current workload it will be difficult to make this work a priority, but i really would like to be able to offer support for the new API (the old one is clunky in various ways). if you have any time/energy to devote to this task, i'm more interested in making sure that it's a project that's fun for you to work on than in making sure it's implemented in exactly the precise way that i would choose :)

ghost commented 8 years ago

Your approach is much more thoroughly thought out than mine were, I like it. I'm assuming HTTP methods would be specified in options? For instance:

# Returns a list of surveys (GET is default)
Surveymonkey.surveys

# Creates a new survey
Surveymonkey.surveys(method: 'post')

The solution I had in mind was to prefix the method call with the request type (this is shown in my first example, but I utterly failed to explain it - my bad):

# Returns a list of surveys
Surveymonkey.get_surveys

# Creates a new survey
Surveymonkey.post_surveys

I feel that this would make a better distinction between the API parameters and the HTTP request itself, but it might be more work than it's worth. And come to think of it, options_surveys would look a little silly.

hakamadare commented 8 years ago

hmmmmmmmmmmmmmmmm. i need to look a bit harder at the APIv3 specification; my naïve assumption is that it should be possible to derive from context (i.e. from which parameters are passed in) what HTTP method should be used, but i could easily be mistaken.

however: i'm creating an initial milestone which will consist of just moving the current Surveymonkey::API to Surveymonkey::API::V2. that should be a backwards-compatible change (b/c of default value of :api_version param), it looks like there aren't any class constants or variables that i'll need to worry about.

then once there's space to make Surveymonkey::API::V3 we can think some more about how it should be implemented.

ghost commented 8 years ago

I haven't been able to dedicate time for experimentation with version 3, but it looks support will need to be added for the gem to continue functioning. Here's an excerpt from an email Surveymonkey recently sent out:

With these changes we will be retiring v1 and v2 of the API, which your integration is built upon. All integrations will need to be rewritten using v3 by December 1, 2016. After this date all older versions of the API will be turned off.

cescue commented 7 years ago

I've had to give up after a few attempts of porting this project to version 3 - The API is just too different. I'm hoping you'll have more success with it if you end up giving it a shot.

If you end up needing a ruby client for version 3, I'm building a new one from scratch right now - it's still very early in development (and nowhere near as sophisticated as this one), but it should work out of the box with version 3.

https://github.com/cescue/monkey-business

Cheers!

nfedyashev commented 6 years ago

@cescue Thanks for your effort! :+1: