0

getting results returned in JSON format

It looks like the default implementation is to return results in XML format. Is there a way to have the results returned as a JSON.

For example, with the URI:
http://fantasysports.yahooapis.com/fantasy...ue/{league_key}

can I specify that I want a JSON returned and not XML???

by
10 Replies
  • Great question. We actually have a couple of secret parameters that aren't mentioned within the primary documentation, mostly because we weren't positive how people would react to our services so we wanted to keep them simple to start with. So yes, you can request JSON as your output format for any of these YDN services. Just append "?format=" to the URL, and type in up, up, down, down, left, rig...

    Wait, sorry, that's a different secret code. Just append "?format=json" to any webservice request, and it should return the same content as JSON instead of XML. Taking your example, try:

    http://fantasysports.yahooapis.com/fantasy...%7D?format=json
    0
  • QUOTE (Sean Montgomery @ Jun 8 2010, 12:41 PM) <{POST_SNAPBACK}>
    Great question. We actually have a couple of secret parameters that aren't mentioned within the primary documentation, mostly because we weren't positive how people would react to our services so we wanted to keep them simple to start with. So yes, you can request JSON as your output format for any of these YDN services.


    This works great, except for the output has numbers at some levels and numbers don't play nice with java script:
    CODE
    {
    "fantasy_content": {
    "users": {
    "0": {
    "user": [
    ]
    }
    }
    }
    }


    When I try to refer to the 0 in javascript, I get errors, javascript only seems to want text. Is there another tag or option or something I can put in the URL to make JSON come back without numbers in the name fields? The XML comes back fine, but I highly prefer JSON data over XML.

    Thanks!

    David
    0
  • Interesting. We're just running a data structure we build up through the PHP function json_encode, so I would have thought that would be pretty bug-proof, but it does look like json_encode does some strange things with mixed or nested associative arrays. The problem here is that collections theoretically ought to be interpreted as arrays, but we're also tossing in a "count" field that throws things out of whack (because that adds an associative element to the collection, meaning it can only be interpreted as an object by json_encode). Do you actually have any thoughts about how that ought to display in JSON? I'm not overly familiar with the layout but it seems like this is a somewhat tricky problem to solve if we want to be able to display collections like users as having counts or start values while still being able to loop through the nested user objects like a normal JS array. I wonder if we need to insert another layer, ie:

    CODE
      <users count="1">
    <user>
    <games count="1">
    <game>
    <game_key>238</game_key>
    <game_id>238</game_id>
    <name>Baseball</name>

    <code>mlb</code>
    <type>full</type>
    <url>http://baseball.fantasysports.yahoo.com/b1</url>
    <season>2010</season>
    </game>
    </games>
    </user>
    </users>


    becomes:

    CODE
    {"users":{"collection":[{"user":{"games":{"collection":[{"game":{"game_key":"238","game_id":"238","name":"Baseball","code":"mlb","type":"full","url":"http:\/\/baseball.fantasysports.yahoo.com\/b1","season":"2010"}],"count":1}}}],"count":1}}


    (ie, using some placeholder like "collection" to mark off the actually array part of the collection)

    Does anyone actually have any JSON implementation that they're happy with that would now break if we started moving around the JSON structure?
    0
  • FYI: still looking into how we might consider changing the JSON output for our services, but one of my coworkers observed that you are able to access properties as array indices in JS, meaning that if you want to get to an element identified as "0" within the JSON request, you could do something like:

    data['fantasy_content']['users']['0']['user']

    which would be functionally equivalent to:

    data.fantasy_content.users.0.user

    If that actually worked (and which I assume was giving you issues before). Similarly, if you needed to try to loop through all of the users, can just for loop through it, ie:

    CODE
    for( key in data.fantasy_content.users ) {
    if( IsNumeric( key ) ) {
    var value = data.fantasy_content.users[key]['user'];
    }
    }


    (or something like that. My JS is terrible. Concept is that you check if the key is numeric to make sure it's one of the members of the collection, not the "count" or "start" field)

    Again, still weird JSON that we're outputting, but this could at least give you a way to play with it for now.
    0
  • Yeah, I'm looking at players collections (NFL, 2010) in JSON and seeing some weird things. As was pointed out, arrays are being used were associative structures are probably more appropriate... I don't have time right now to post a detailed description of what the output looks like, what (I think) would be more ideal, and why, but hopefully I'll be able to get to it in a few hours.

    Here's one vote for maybe changing it at the expense of breaking preexisting apps...

    - BW
    0
  • Okay, well here is a sample players collection with two players, in JSON format (I pretty printed it):

    CODEBOX
    {
    "fantasy_content":{
    "xml:lang":"en-US",
    "yahoo:uri":"\/fantasy\/v2\/game\/242\/players;count=2;start=0",
    "game":[
    {
    "game_key":"242",
    "game_id":"242",
    "name":"Football",
    "code":"nfl",
    "type":"full",
    "url":"http:\/\/football.fantasysports.yahoo.com\/f1","season":"2010"
    },
    {
    "players":{
    "0":{
    "player":[
    [
    {
    "player_key":"242.p.8801"
    },
    {
    "player_id":"8801"
    },
    {
    "name":{
    "full":"Chris Johnson",
    "first":"Chris",
    "last":"Johnson",
    "ascii_first":"Chris",
    "ascii_last":"Johnson"
    }
    },
    {
    "editorial_player_key":"nfl.p.8801"
    },
    {
    "editorial_team_key":"nfl.t.10"
    },
    {
    "editorial_team_full_name":"Tennessee Titans"
    },
    {
    "editorial_team_abbr":"Ten"
    },
    {
    "bye_weeks":{
    "week":"9"
    }
    },
    {
    "uniform_number":"28"
    },
    {
    "display_position":"RB"
    },
    {
    "image_url":"http:\/\/l.yimg.com\/a\/i\/us\/sp\/v\/nfl\/players_l\/headshots\/20100903\/8801.jpg?x=46&y=60&xc=1&yc=1&wc=165&hc=215&q=100&sig=Pw6JaMEEqffWUkzcdUI0dQ--"
    },
    {
    "is_undroppable":"0"
    },
    {
    "eligible_positions":[
    {
    "position":"RB"
    }
    ]
    },
    {
    "has_player_notes":1
    },
    {
    "has_recent_player_notes":1
    }
    ]
    ]
    },
    "1":{
    "player":[
    [
    {
    "player_key":"242.p.8261"
    },
    {
    "player_id":"8261"
    },
    {
    "name":{
    "full":"Adrian Peterson",
    "first":"Adrian",
    "last":"Peterson",
    "ascii_first":"Adrian",
    "ascii_last":"Peterson"
    }
    },
    {
    "editorial_player_key":"nfl.p.8261"
    },
    {
    "editorial_team_key":"nfl.t.16"
    },
    {
    "editorial_team_full_name":"Minnesota Vikings"
    },
    {
    "editorial_team_abbr":"Min"
    },
    {
    "bye_weeks":{
    "week":"4"
    }
    },
    {
    "uniform_number":"28"
    },
    {
    "display_position":"RB"
    },
    {
    "image_url":"http:\/\/l.yimg.com\/a\/i\/us\/sp\/v\/nfl\/players_l\/headshots\/20100903\/8261.jpg?x=46&y=60&xc=1&yc=1&wc=165&hc=215&q=100&sig=_xAFTbo7jcxfkCVyTkZmTg--"
    },
    {
    "is_undroppable":"0"
    },
    {
    "eligible_positions":[
    {
    "position":"RB"
    }
    ]
    },
    {
    "has_player_notes":1
    },
    {
    "has_recent_player_notes":1
    }
    ]
    ]
    },
    "count":2
    }
    }
    ],
    "time":"349.18189048767ms",
    "copyright":"Data provided by Yahoo! and STATS, LLC"
    }
    }


    As you can see there are a few weird things here.

    1. First, the "game" object is a list with two hashes* in it. Since I can't trust that these will always show up in the same order, I have to manually look into the hashes to see what's in each one. Not really a big deal, but weird. The second hash has one element, called "players". Maybe it's better to use a hash for the "game" object, something like "game_metadata" could be the key for the first element and "players" the key for the second...

    2. Secondly, "players" is a hash containing numbers as keys... and one of the keys is the string "count." So if I make a list of all the keys of "players" and traverse it in order to find "player" objects, I have to check that I'm not getting the "count" object on each iteration. Again, not the end of the world, but weird. If it were me, I'd have a hash with an element called "count" and an element called "players_list" or "players_hash" that holds the actual "player" objects.

    3. Okay, so then we get into the player object... a list which contains one list. Still weird.

    4. Finally, we get into the "player" object, which (once we nest down one list; see point 3), is really just a list of one element hashes. Just using a hash instead is clearly a better solution for a few reasons: it's quicker and easier to program in languages that support hashes and lists (perl, python, etc), and it doesn't require a list traversal just to find an element.

    5. Finally, there's some weirdness when you look at "bye_weeks" - shouldn't this be a list of "week" objects? In the current scheme, how do you handle players with multiple bye weeks (maybe they get traded). And if you assume each player can have only one bye week, then is the "week" object even necessary? You could just have "bye_week" which would hold an integer.

    Okay, so I'm nitpicking on some of these, especially 5. But I think that 1, 2 and 4 deserve some thought.

    Sean, I'm sure your internal data representation makes plenty of sense, and I also imagine it's something you can't just start changing around! As you alluded to, it seems like your json_encode function does some weird stuff. I don't really use PHP so I don't know much about that... but perhaps an alternate implementation with different behavior is a good solution here.

    I'm new here so I don't know how this community works, but I'd be willing to contribute if anyone thinks these are good ideas.

    - Brian Waters

    * To be clear, what I'm calling a hash, you might alternately know as an associative array, dictionary or map.

    P.S. Sean, thanks for your awesome support and interest in these forums.
    0
  • Thanks for the analysis, Brian. :)Given that the XML interface was our primary focus (and the JSON option was basically just inherited from the webservice framework that we'd written), it would certainly be safer to try to build off of the XML instead. The bug for trying to fix up the JSON is in our system, but it's not our highest priority right now.
    0
  • Sean,

    Thanks for the response.

    After I wrote that post, I sat down and wrote a parser for that JSON in perl. It's ugly, but it works just fine. I'll take your advice about sticking to XML to heart.

    - Brian
    0
  • for those of us using regular Java who stumble on this thread, I'm using XML but then converting it to JSON using the XML utilities available here:
    http://www.json.org/java/
    0
  • hi...

    What parameters need to send in the blow query to work with my ios app

    http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20fantasysports.leagues%20where%20league_key%3D'238.l.627060'&format=json&diagnostics=true&callback=getData

    the above query works fine in YQL console but its give authorization error while i work with this query in IOS

    If any one please modify the query atleast the parameter need to send rest I will try to debug any help would be really thankfull

    0

Recent Posts

in Fantasy Sports API