There is a scenario for example as in any Application Controller while exposing a rest api we can make PathParams/UriParams as optional at controller level, so it wouldn't required always for client to pass it. Now I want to achieve same at RAML level. I can see their documentation that says like this.
"Although a URI parameter MAY be explicitly specified as optional, it
SHOULD be required when surrounded directly by slashes (/). In this
case, the URI parameter constitutes a complete URI path fragment, for
example .../{objectId}/.... It usually makes no sense to allow a URI
to contain adjacent slashes, enclosing no characters, for example,
...//.... Therefore, a URI parameter SHOULD be specified as optional
only when it appears adjacent to other text. For example,
/people/~{fieldSelectors} indicates that URI parameter
{fieldSelectors} can be blank, and therefore optional, which implies
that /people/~ is a valid relative URI."
That does give sense that we can try with combination of letter e,g /{someLetter}{uriParam} .. at end of resource Url. I did try this way but it always mention that "resouce not found"
Issue is just related to RAML configuration. for example this is sample resource url for which I have to add url param.
/test-api/{testId}
Now I want to keep it the client decision to either pass UriParameter or not.
This is sample RAML code I am trying.
/test-api/{testId}:
uriParameters:
testId?: string
/test-api/{testId}:
uriParameters:
testId: string
required: false
/test-api{testId}:
uriParameters:
testId: string
Now all three approaches aren't working.
1st approach simply making testId as optional using '?'. But if I skip UriParam it shows that no resource found for this.
2nd approach with required: false also not working looks like RAML is ignoring this validation it always expect even a single '/' from me after /test-api
3rd approach isn't working because it again expect me to put UriParam otherwise consider default one.
To subscribe to the automatic insertion of the URI parameter in RAML 1.0 make this change:
/test-api:
/{testId}:
uriParameters:
testId:
description: Id of test
type: string
required: false
get:
description: return test
responses:
200:
body:
application/json:
example: { "message": "success" }
put:
description: update test
responses:
200:
body:
application/json:
example: { "message": "success" }
delete:
description: remove test
responses:
200:
body:
application/json:
example: { "message": "success" }
Related
Consider HTML. You write a tag <img src="http://example.com/image.png"/> and the browser retrieves the image at the location specified. I'm designing my API to use a similar mechanism where it's up to the server where any secondary resources and it supplies the location of those resources in the form of a URL.
I'm writing an OpenAPI document to describe all the JSON structures that are sent up to and returned by the server. It works great except I don't know how to express the relationship between the URL inside the response to the first resource to the second resource.
openapi: 3.0.3
info:
title: Minimal Spec for Question.
version: 0.0.0
paths:
/firstRefToSecond:
get:
description: Gets some data including a reference to a secondary resource.
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
properties:
RefToSecond:
type: string
description: The URL to the second resource.
example: "http://example.org/second"
/secondResourceExampleUrlNotActuallyThisUrl:
get:
description:
The second resource.
Found at the URL pointed to by RefToSecond.
responses:
'200':
description: Successful operation
content:
application/json:
schema:
type: object
properties:
Data:
type: integer
description: The data.
example: 12
Here, the second "path" is simply a placeholder for the second URL. I would prefer not to have that placeholder at all and instead substitute the path for wherever that URL points.
Is there a way in OpenAPI to express this relationship between the "refToSecond" URL property and the requirements of what that secondary interaction would look like, without linking it to an explicit URL set in advance?
Is there a way in OpenAPI to express this relationship between the "refToSecond" URL property and the requirements of what that secondary interaction would look like, without linking it to an explicit URL set in advance?
It is possible to formally express a relationship between the response of an operation and another request URL: See the Link feature. The section "Runtime Expression Syntax" is apparently helpful for your case. (Disclaimer: I have never seen this feature being used anywhere in practice so far.)
But this only allows to express the relation to the operation that is available at the server-defined URL. You cannot specify dynamic endpoints in OpenAPI, so you cannot provide a detailed description of the request and response (except in the way you showed in the question).
As far as I know there is no way to attach few keys to the single value in {key : value} pair in YAML.
I am new to Swagger documentation (OpenAPI 3.0) and wondering is it possible somehow to combine my values together.
For instance, I am messing with REST API documentation and when I want to list few responses without rewriting it every time, I have the following :
paths:
/users:
post:
//some additional information here
responses:
'500':
//and for example here I want to add not only 201 status code but also others
description: >-
Something went wrong on back end
//however I have to do something like this (writing them all)
'502':
description: >-
Something went wrong on back end
//and so on..
What is best practices to overcome that? Maybe I have a bad point from the beginning.
You can use anchors and aliases:
path:
/users:
responses:
'500':
description: &desc1 >-
Something went wrong on back end
'502':
description: *desc1
OpenAPI 3.0 supports response ranges '1XX'-'5XX' that can be used instead of listing the codes individually:
responses:
'5XX':
description: Something went wrong on back end
If you still want to list the response codes individually but they have the same description and schema, you can $ref the common response definition like so:
responses:
'501':
$ref: '#/components/schemas/BackendErrorResponse'
'502':
$ref: '#/components/schemas/BackendErrorResponse'
components:
responses:
BackendErrorResponse:
description: Something went wrong on back end
content:
application/json:
schema:
...
There's also an enhancement request in the OpenAPI Specification repository to allow reusing description across different responses.
I am building my first RESTful API for practising and learning. I am using RAML and will realize it with MuleSofts AnypointStudio. I don't really know how to deal with responses, particularly, error responses. I managed to figure out which HTTP status codes I want for my responses but didn't manage to figure out how to handle the response messages.
Do I need to define response datatype and example message for every response code (200, 201, 204, 404 etc.)? If I can have one datatype and one example message, how do I do use them accordingly?
Currently, I have defined one error type and one example message.
Error.raml
#%RAML 1.0 DataType
type: object
description: This general error structure is used throughout this API.
properties:
code:
type: integer
minimum: 400
maximum: 599
description?:
type: string
default: "Bad query parameter [$size]: Invalid integer value [abc]"
example: The server understood the request, but is refusing to fulfill it
reasonPhrase?:
type: string
examples:
example: Bad Request
example1: Forbidden
example: !include ../examples/error_example.json
error_example.json
{
"code": 400,
"description": "Bad query parameter [$size]: Invalid integer value [abc]",
"reasonPhrase": "Bad Request"
}
As you can see, I have variables in both datatype and example message. They were generated by Restlet. I don't know how to utilise them yet so I just left them for the time being.
Would really appreciate any help and tips.
Do I need to define response datatype and example message for every response code (200, 201, 204, 404 etc.)? If I can have one datatype and one example message, how do I do use them accordingly?
No you don't. For a resource you could specify responses such as 200 or 404 (these are the most commonly used)
From the docs:
resourceTypes:
collection:
description: Collection of available songs in Jukebox
get:
description: Get a list of songs based on the song title.
responses:
200:
body:
application/json:
post:
description: |
Add a new song to Jukebox.
queryParameters:
access_token:
description: "The access token provided by the authentication application"
example: AABBCCDD
required: true
type: string
body:
application/json:
type: song
responses:
200:
body:
application/json:
example: |
{ "message": "The song has been properly entered" }
An example of a resource with a not found error:
collection-item:
description: Entity representing a <<resourcePathName|!singularize>>
get:
description: |
Get the <<resourcePathName|!singularize>>
with <<resourcePathName|!singularize>>Id =
{<<resourcePathName|!singularize>>Id}
responses:
200:
body:
application/json:
404:
body:
application/json:
example: |
{"message": "<<resourcePathName|!singularize>> not found" }
There's an excellent blog post about this. Have a look at RAML tutorials as they have nice docs.
You could also have a look at Swagger for more "inspiration".
I think I hit an AWS API Gateway scenario that doesn't appear to have a solution.
I am trying to create a json POST endpoint to validate an address against a USPS service.
The ultimate request looks like this:
http://production.shippingapis.com/ShippingAPI.dll?API=Verify&XML=<AddressValidateRequest USERID="SECRET"><Address><Address1>101 Foo Lane</Address1></Address2><City>Somewhereville</City><State>CA</State><Zip5>90210</Zip5><Zip4></Zip4></Address></AddressValidateRequest>
The issue I'm having is I need to set the XML query string parameter based on my passed in method body, e.g.:
{
address: "101 Foo Lane",
city: "Somewhereville",
state: "CA",
zip: "90210"
}
It appears in the Integration Request, I can specify the "Mapped from", but I can't access the method body, only the method.request.{"path", "querystring" | "header"}.{param_name}
Also there doesn't appear for me to construct a param_name value in the Method Request setup from the incoming method body.
The XML to JSON response mapping is working great if I provide a hard coded XML query string, so I'm down to just the request mapping.
You can map the body to request parameter using method.request.body.JSONPath_EXPRESSION but you can't construct the request parameter using a template similar to what can be done for integration request body. All the available mappings are documented here - http://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html
Learning about REST APIs and am following https://apihandyman.io/writing-openapi-swagger-specification-tutorial-part-2-the-basics/.
The API can receive two parameters: username and bla, but only username is required by using the required keyword. This makes sense to me.
The API will return firstname, lastname, and username, but only username is required by using the required keyword. This does not make sense to me. Does the lack of the required keyword indicate that the other two might sometimes not be required? What influences whether they are or are not?
paths:
/persons/{username}:
get:
summary: Gets a person
description: Returns a single person for its username.
parameters:
- name: username
in: path
required: true
description: The person's username
type: string
- name: bla
in: query
description: bla bla bla
type: string
responses:
200:
description: A Person
schema:
required:
- username
properties:
firstName:
type: string
lastName:
type: string
username:
type: string
404:
description: The Person does not exists.
Your interpretation is correct. If a property of a response object is listed in the required property list, is must be present in the response object for it to be valid, quite similar to the required field in a parameter object. Whether a non-required property is included in the response or not is up to the business logic of your application to decide.
Some more information with pointers to the relevant parts of the specification below:
The semantics of the required property list of a response object is defined as part of the Schema Object section of the OpenAPI specification. There it says that the schema object "is based on the JSON Schema Specification Draft 4 and uses a predefined subset of it".
In the corresponding section on the required validation keyword of the JSON Schema Validation specification its semantics is defined as follows:
5.4.3. required
5.4.3.1. Valid values
The value of this keyword MUST be an array. This array MUST have at
least one element. Elements of this array MUST be strings, and MUST be
unique.
5.4.3.2. Conditions for successful validation
An object instance is valid against this keyword if its property set
contains all elements in this keyword's array value.
You'll find further examples of how the required keyword can be used in the examples section of the JSON Schema specification or Part 5, Section 2.2 of the tutorial you're following.