API blueprint MSON to define valid Attribute values? - validation

Consider this excerpt from https://github.com/apiaryio/mson#example-1 ...
Example 1
A simple object structure and its associated JSON expression.
MSON
- id: 1
- name: A green door
- price: 12.50
- tags: home, green
Let's say I would like to define valid values for the name attribute. Consider a context of API testing with a tool such as Dredd. We may need to define what are the expected/valid name values in response to GET'ing this resource, or else something is probably broken and this test step should fail.
And/or, if creating/updating a resource of this type, we may need to define what name values are valid/accepted. Is this currently possible to define in MSON?
(I believe this can be done in a JSON schema, which makes me hopeful for MSON support.)
Following is an example API Blueprint resource to illustrate how this would be used...
# Thing ID [/api/thing/id]
# List Thing ID attributes [GET]
+ Response 200
+ Attributes
+ href (string)
+ make (string)
+ model (string)
+ version (string)
+ Body
{"href":"/api/thing/id","make":"BrandX","model":"SuperThingy","version":"10.1"}
In the above example, there are 3 known/accepted/valid values for the model attribute: CoolThingy, AwesomeThingy, and MLGThingy
Can we represent this resource in MSON, such that...
Apiary (or other rendered) API documentation consumers can easily know what model values to expect?
Dredd processes and passes/fails the model value in the response to a GET to this resource?

In MSON you can use enum, see the example below.
name (enum[string])
joe (default)
ben
mark

Related

API Blueprint: Semantic Issue "no value(s) specified"

In my blueprint I'm defining a data structure and try to use it like so
+ Attributes
+ error: (Error Details, required)
Data structure definition at the end of the document:
# Data Structures
## Error Details
+ code : 1234 (number, required) - see list of error codes
+ message: User not found (string, required) - a human-readable error message
The resulting sample response body looks just like expected but the validation on apiary.io shows semantic issues for each of the places where I use constructs like this, saying "No value(s) specified".
Am I doing something wrong or is it a problem with the apiary.io parser?
I had the same problem and solved it by
omitting the colon
separating the object definition and type (see owner in this example):
Company (object)
name: Company name (string)
owner (OwnerResponse) (object)
A similar answer to other current answers, but none the less this fixed it for me.
No good:
+ Attributes
+ `status`: OK
+ `data`:
+ 5 (Channeldata)
+ 7 (Channeldata)
Fix:
+ Attributes
+ `status`: OK
+ `data`
+ 5 (Channeldata)
+ 7 (Channeldata)
As others have noted, losing a colon in the right place can fix things.
Attribute section can be also defined as + Attributes <Type Definition> (specification), so defining + Attributes (Error Details, required) should fix the given semantic issue.
Edit:
You have to omit a colon between attribute's name and its type, when an example value is not defined:
+ Attributes
+ error (Error Details, required)
Missed that before, sorry.

Is Django REST Framework's HyperlinkedRelatedField unable to reference url patterns with multiple kwargs?

I have a REST api url endpoint that represents a Song within an Album:
/api/album/(?P<album_id>)/song/(?P<id>)/
and I want to refer to it from another resource, e.g. Chart that contains Top-1000 songs ever. Here's an implementation of ChartSerializer:
class ChartSerializer(HyperlinkedModelSerializer):
songs = HyperlinkedRelatedField(
queryset=Song.objects.all(),
view_name='api:song-detail',
lookup_field='id'
)
class Meta:
model = Chart
fields = ('songs', )
Clearly, I can pass id as lookup_field, but it seems to me that I won't be able to pass album_id by any means. I'm looking into HyperlinkedModelSerializer.get_url() method:
def get_url(self, obj, view_name, request, format):
"""
Given an object, return the URL that hyperlinks to the object.
May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
attributes are not configured to correctly match the URL conf.
"""
# Unsaved objects will not yet have a valid URL.
if hasattr(obj, 'pk') and obj.pk in (None, ''):
return None
lookup_value = getattr(obj, self.lookup_field)
kwargs = {self.lookup_url_kwarg: lookup_value}
return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
As you can see, it constructs kwargs for reverse url lookup from scratch and doesn't allow to pass additional parameters to it. Am I right that this is not supported?
UPDATE:
Found a reference to this problem in the issue list of DRF: https://github.com/tomchristie/django-rest-framework/issues/3204
So, the answer is YES. There is even a paragraph about this issue in the DRF documentation:
http://www.django-rest-framework.org/api-guide/relations/#custom-hyperlinked-fields

Documenting Mutually Exclusive Query Parameters in API Blueprint

I'm documenting a public API that has a method named /findGuild that takes a mandatory key parameter and one of the following parameters:
byPlayer
byName
It must have either byPlayer or byName; My question is: How do I indicate that byPlayer and byName are mutually exclusive, but one is mandatory?
Right now, I have the following in my .apib for this Resource:
### GET /findGuild{?byName,byPlayer,key}
+ Parameters
+ byName: `YourGuild` (string, optional) - Search for the Guild by its name.
+ byPlayer: (string, optional) - Search for Guild by a player. Does not seem to work.
+ key: `ffffffff-ffff-ffff-ffff-ffffffffffff` (string, required) - The user's API key.
+ Response 200 (application/json)
+ Attributes (object)
+ guild (string) - The guild id or null.
+ success (boolean) - Should be true.
+ Body
{
"guild": "ffffffffffffffffffffffff",
"success": true
}
I am afraid (but not totally sure) API Blueprint is not capable of expressing this kind of relationship at the moment.
What I can surely tell you is that, according to public roadmap, URI Parameters will be replaced with an MSON object, which supports the scenario you're asking for.
Hope it helps!

Blueprint API show all possible values for Enum in Response Body

When writing an API-Deocumentation for an rest-service I came across an problem where I wanted to list all the possible Values which could be returned as a response.
In the case below it would be the "state" field which could contain any possible value of a enumeration and I wanted to sum up which possible states there are.
I could not find an easy and nice way to do it with apiblueprint. Is there a way to display sections collapsed by default and expand them when additional information is needed?
Here is the Sample code I have:
## Sample [/Sample?{id}]
Get all the information for the sample
+ Parameters
+ id = `0` (Integer, optional) ... The Id of the resource to get
+ Model (application/json)
+ Body
{
"name": "Name of the Resource",
"state": "deleted"
}
### Retrieve the sample data of the system [GET]
+ Response 200
[ProviderConfiguration][]
I need something like "Values" for the parameters section but for the Body part to describe the state in the Body section e.g.
<collapsible>
+ state (EnumType) ... current state of the sample object
+ Values
+ `active`
+ `inactive`
+ `deleted`
</collapsible>
Unfortunately, this is not yet possible with API Blueprint. However, it's planned - see https://github.com/apiaryio/api-blueprint/issues/25 and https://github.com/apiaryio/mson.

JMeter Nested Variable Reference with JDBC Resultset Variable and Counter Variable

I need to query a MYSQL Database for a list of siteIDs and siteURLs. I've specified these names in the JDBC Request's Variable Name field.
Then I created a ForEach Logic Controller to cycle through the siteURLs ${siteURL_1} till the last record from the result as such:
Input Variable Prefix: siteURL
Start Index: 0
End Index: 40
Output Variable Name: newSiteURL
Then I use this in the HTTP Request's Path field as:
${newSiteURL}
This works fine and the HTTP requests are going through.
Now, I want to name the HTTP Requests properly so that they are indexed better.
For that, I decided to use the siteID field from the result set.
To do that, I created a counter variable as such:
Start: 1
Increment: 1
Maximum: 40
Reference Name: siteIndex
Now, to get the siteID from the result show in the corresponding HTTP Request, I edited the Name field of the HTTP Request to this:
${siteID_"({siteIndex})"}
But my HTTP Requests in the View Results Tree still end up showing as:
${siteID_"({siteIndex})"}
${siteID_"({siteIndex})"}
${siteID_"({siteIndex})"}
${siteID_"({siteIndex})"}
${siteID_"({siteIndex})"}
...
And not the actual siteID for the corresponding siteURL in the HTTP Request like:
21231
12315
21654
64574
76876
...
You need to change this bit:
${siteID_"({siteIndex})"}
to
${__V(siteID_${siteIndex})}
Explanation:
As per __V function documentation
For example, if one has variables A1,A2 and N=1:
${A1} - works OK
${A${N}} - does not work (nested variable reference)
${__V(A${N})} - works OK. A${N} becomes A1, and the __V function returns the value of A1
See Using JMeter Functions post series for more examples on how to get things done with useful JMeter Functions.

Resources