Specify query parameter for a single HTTP method - apiblueprint

To illustrate my problem, I made a condensed example from the Apiary.io blueprint tutorial.
FORMAT: 1A
# Gist Fox API
# Group Gist
Gist-related resources of *Gist Fox API*.
## Gists Collection [/gists{?since}]
### List All Gists [GET]
+ Parameters
+ since (optional, string) ... Timestamp in ISO 8601 format: `YYYY-MM-DDTHH:MM:SSZ` Only gists updated at or after this time are returned.
+ Response 200
{
items: []
}
### Create a Gist [POST]
To create a new Gist simply provide a JSON hash of the *description* and *content* attributes for the new Gist.
+ Request (application/json)
{
"description": "Description of Gist",
"content": "String content"
}
+ Response 201
{
}
Then in my apiary documentation I get the following:
GET /gists{?since}
POST /gists{?since}
However, for me it makes sense to have the since query parameter only for the GET request. Unfortunately I didn't find a way to achieve this result:
GET /gists{?since}
POST /gists
Is it something possible?

Update
(Thursday, 23 Oct 2014)
The fix has been deployed; could you please give it a try and let me know if everything works as expected?
The bad news
It is our (Apiary) bug and you're not doing anything wrong :-(
The good news
It is a known bug we are currently working on and it is going to be fixed with the end of this week (Sunday, 19 Oct 2014) :-)

Related

Testing REST routes with cURL - data not saving

I am running through the tutorials in Open REST Routes but I am now stuck at posting data to the mongodb posts collection.
When I cURL it executes without error but my title and link are not saved and the upvotes defaults to 0 as defined in the schema.
My Post schema is:
var mongoose = require('mongoose');
var PostSchema = new mongoose.Schema({
title: String,
link: String,
upvotes: {type: Number, default: 0},
comments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Comment'}]
});
mongoose.model('Post', PostSchema);
I get the result below:
curl http://localhost:3000/posts -d '{"title":"Go Bigdadi! Nicely done!!!","link":"http://www.foo.com","upvotes":2}'
{"upvotes":0,"comments":[],"_id":"5b740c875bdf6a326c677cd3","__v":0}`
Please suggest where I am likely to be messing it up.
I think I have figured it out....
I tried changing the parameters round a bit and was able to get the expected result.
I tried:
curl http://localhost:3000/posts -i -X POST -d "title=Bigdadi Rules Posts&link=http://www.foo.com&upvotes=2"
It works!!!

Ruby Hash and Tumblr API

controller page, Json output from api
I'm trying to display posts from the users tumblr account on my view page using ruby. I have never done anything with api's before. I'm trying to use Hash tables. my controller code is as such:
#Posts = client.posts"zombieprocess1.tumblr.com"
on my view page using html I have
<%=Posts%>
the response is such
{"blog"=>{"title"=>"Untitled", "name"=>"zombieprocess1", "total_posts"=>1, "posts"=>1, "url"=>"URL", "updated"=>1478191052, "description"=>"", "is_nsfw"=>false, "ask"=>false, "ask_page_title"=>"Ask me anything", "ask_anon"=>false, "followed"=>false, "can_send_fan_mail"=>true, "is_blocked_from_primary"=>false, "share_likes"=>true, "likes"=>1, "twitter_enabled"=>false, "twitter_send"=>false, "facebook_opengraph_enabled"=>"N", "tweet"=>"N", "facebook"=>"N", "followers"=>0, "primary"=>true, "admin"=>true, "messages"=>0, "queue"=>0, "drafts"=>0, "type"=>"public", "reply_conditions"=>3, "subscribed"=>false, "can_subscribe"=>false}, "posts"=>[{"blog_name"=>"zombieprocess1", "id"=>152689921093, "post_url"=>"URL", "slug"=>"", "type"=>"photo", "date"=>"2016-11-03 16:37:32 GMT", "timestamp"=>1478191052, "state"=>"published", "format"=>"html", "reblog_key"=>"NCDqGTzW", "tags"=>[], "short_url"=>"URL", "summary"=>"", "recommended_source"=>nil, "recommended_color"=>nil, "followed"=>false, "liked"=>true, "note_count"=>1, "caption"=>"", "reblog"=>{"tree_html"=>"", "comment"=>""}, "trail"=>[], "image_permalink"=>"url", "photos"=>[{"caption"=>"", "alt_sizes"=>[{"url"=>"URL", "width"=>400, "height"=>544}, {"url"=>"URL", "width"=>250, "height"=>340}, {"url"=>"URL", "width"=>100, "height"=>136}, {"url"=>"URL", "width"=>75, "height"=>75}], "original_size"=>{"url"=>"URL", "width"=>400, "height"=>544}}], "can_like"=>false, "can_reblog"=>true, "can_send_in_message"=>true, "can_reply"=>true, "display_avatar"=>true}], "total_posts"=>1}
I have tried many different formats and can't seem to just get the post url. My thought is to get the post_url and embed each of them so it shows as it would in tumblr on my webpage. Can anyone help me?
Try this:
#posts['posts'].first['post_url']
Or if your response contains more than one post you can return them all like this:
(0...#posts['total_posts']).map { |i| #posts['posts'][i]['post_url'] }
EDIT: Fixed capitalization in second line of code. I assume you are using lowercase variable as per Ruby convention, '#posts'. If not, you should change to a lowercase variable as this may be confusing something.

API Blueprint and Dredd - Required field missing from response, but tests still pass

I am using a combination of API Blueprint and Dredd to test an API my application is dependent on. I am using attributes in API blueprint to define the structure of the response's body.
Apparently I'm missing something though because the tests always pass even though I've purposefully defined a fake "required" parameter that I know is missing from the API's response. It seems that Dredd is only testing whether the type of the response body (array) rather than the type and the parameters within it.
My API Blueprint file:
FORMAT: 1A
HOST: http://somehost.net
# API Title
## Endpoints [GET /endpoint/{date}]
+ Parameters
+ date: `2016-09-01` (string, required) - Date
+ Response 200 (application/json; charset=utf-8)
+ Attributes (array[Data])
## Data Structures
### Data
- realParameter: 2432432 (number)
- realParameter2: `some string` (string, required)
- realParameter3: `Something else` (string, required)
- realParameter4: 1 (number, required)
- fakeParam: 1 (number, required)
The response body:
[
{
"realParameter": 31,
"realParameter2": "some value",
"realParameter3": "another value",
"realParameter4": 8908
},
{
"realParameter": 54,
"realParameter2": "something here",
"realParameter3": "and here too",
"realParameter4": 6589
}
]
And my Dredd config file:
reporter: apiary
custom:
apiaryApiKey: somekey
apiaryApiName: somename
dry-run: null
hookfiles: null
language: nodejs
sandbox: false
server: null
server-wait: 3
init: false
names: false
only: []
output: []
header: []
sorted: false
user: null
inline-errors: false
details: false
method: []
color: true
level: info
timestamp: false
silent: false
path: []
blueprint: myApiBlueprintFile.apib
endpoint: 'http://ahost.com'
Does anyone have any idea why Dredd ignores the fact that "fakeParameter" doesn't actually show up in the response body and still allows the test to pass?
You've run into a limitation of MSON, the language API Blueprint uses for describing attributes. In many cases, MSON describes what MAY be present in the data structure rather than what MUST exactly be present.
The most prominent case are arrays, where basically any content of the array is optional and thus the underlying generated JSON Schema doesn't put any constraints on array contents. Dredd just respects that, so indirectly it becomes a Dredd issue too, however there's not much Dredd can do about it.
There's an issue for the problem: apiaryio/mson#66 You can follow and comment under the issue to get updated about this. Dredd is usually very prompt in getting the latest API Blueprint parser, so once it's implemented in the language itself, it won't take long to appear in Dredd.
Obvious (but tedious) workaround is to specify your own JSON Schema with stricter rules using the + Schema section alongside the + Attributes section.

Different request on same action with parameters

I want to search (say) "accounts" based on "name" or "status".
So I would like to have two actions :
GET /persons/?q=name==Jea*
GET /persons/?q=status==locked
How can I document that ?
I tried an Action with multiples transactions :
### GET /accounts{?q}
+ Request by name
+Parameters
+q (required, FIQLQuery)
**Only name is supported**
+ Request by status
+Parameters
+q (required, FIQLQuery)
**Only status is supported**
But Apiary editor complains because :
I must provide a message-body for my GET requests:
Message-body asset is expected to be a pre-formatted code block, every of its line indented by exactly 8 spaces or 2 tabs.
The + Parameters block is not recognized :
Ignoring unrecognized block
Thanks a lot
i can make solution that works for me.
Try this API Blueprint:
FORMAT: 1A
# requestByname
## Accounts [/accounts/?{q,type}]
### GET
+ Parameters
+ q (required, FIQLQuery)
+ type (string, `name` or `status`)
+ Request Name (application/json)
+ Response 200
{"name": "test"}
+ Request Status (application/json)
+ Response 200
{"status": 200}

How to access Youtube_it ruby query results?

I am trying to implement the youtube_it youtube api wrapper for ruby and have it working except I'm stumped as to how the query results should be accessed.
Here is my query:
client.videos_by(:query => "penguin", :max_results => 1)
Submitting request [url=http://gdata.youtube.com/feeds/api/videos?max-results=1&start-index=1&vq=penguin].
=> #<YouTubeIt::Response::VideoSearch:0xb6c41b14 #feed_id="http://gdata.youtube.com/feeds/api/videos", #updated_at=Wed Nov 03 18:01:39 UTC 2010, #videos=[#<YouTubeIt::Model::Video:0xb6c424d8 #thumbnails=[#<YouTubeIt::Model::Thumbnail:0xb6c6b694 #url="http://i.ytimg.com/vi/oSbLpQEZP1Y/2.jpg", #width=120, #height=90, #time="00:01:34">, #<YouTubeIt::Model::Thumbnail:0xb6c6b248 #url="http://i.ytimg.com/vi/oSbLpQEZP1Y/1.jpg", #width=120, #height=90, #time="00:00:47">, #<YouTubeIt::Model::Thumbnail:0xb6c6a988 #url="http://i.ytimg.com/vi/oSbLpQEZP1Y/3.jpg", #width=120, #height=90, #time="00:02:21">, #<YouTubeIt::Model::Thumbnail:0xb6c69e34 #url="http://i.ytimg.com/vi/oSbLpQEZP1Y/0.jpg", #width=320, #height=240, #time="00:01:34">], #categories=[#<YouTubeIt::Model::Category:0xb6ca5d6c #term="Music", #label="Music">], #noembed=false, #racy=false, #favorite_count=7862, #duration=188, #author=#<YouTubeIt::Model::Author:0xb6c9942c #name="wili", #uri="http://gdata.youtube.com/feeds/api/users/wili">, #updated_at=Tue Nov 02 08:45:25 UTC 2010, #longitude=nil, #position=nil, #view_count=1682350, #html_content="penguin", #media_content=[#<YouTubeIt::Model::Content:0xb6c770d4 #url="http://www.youtube.com/v/oSbLpQEZP1Y?f=videos&app=youtube_gdata", #duration=188, #format=#<YouTubeIt::Model::Video::Format:0xb656d108 #name=:swf, #format_code=5>, #default=true, #mime_type="application/x-shockwave-flash">, #<YouTubeIt::Model::Content:0xb6c766d4 #url="rtsp://v5.cache3.c.youtube.com/CiILENy73wIaGQlWPxkBpcsmoRMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp", #duration=188, #format=#<YouTubeIt::Model::Video::Format:0xb656d11c #name=:rtsp, #format_code=1>, #default=false, #mime_type="video/3gpp">, #<YouTubeIt::Model::Content:0xb6c75d38 #url="rtsp://v8.cache3.c.youtube.com/CiILENy73wIaGQlWPxkBpcsmoRMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp", #duration=188, #format=#<YouTubeIt::Model::Video::Format:0xb656d0f4 #name=:three_gpp, #format_code=6>, #default=false, #mime_type="video/3gpp">], #description="penguin", #latitude=nil, #title="penguin", #published_at=Mon May 08 18:11:01 UTC 2006, #player_url="http://www.youtube.com/watch?v=oSbLpQEZP1Y&feature=youtube_gdata_player", #rating=#<YouTubeIt::Model::Rating:0xb6c5eb4c #min=1, #max=5, #average=4.676985, #rater_count=2746>, #keywords=["pigloo", "penguin"], #video_id="http://gdata.youtube.com/feeds/api/videos/oSbLpQEZP1Y", #where=nil>], #total_result_count=291282, #offset=1, #max_result_count=1>
I would like to retrieve the URL and thumbnail links. Any ideas?
I don't have a great deal of knowledge of this particular gem, but your answer should at least be close to this. You can access the object directly through the videos accessor, which will give you the video object, on which thumbnails each have a url. so you could do the following:
reply = client.videos_by(:query => "penguin", :max_results => 1)
reply.videos.first.thumbnails.first.url # the thumbnail for the first video
reply.videos.first.player_url # The website for the video
reply.videos.first.media_content.first.url # direct embed url
It might be useful to search for some ruby beginners guides to help catch you up to speed as well. Good luck!
william's answer is correct, when you do it
client.videos_by(:query => "penguin", :max_results => 1)
this return an array called videos, so you just need iterate it
client.videos.each do |video|
video.title
video.thumbnails
video.video_id
end
good luck!

Resources