in:query and in:header parameters in yaml file - java

I'm learning creating rest Api using spring boot. FOr reference I was checking some existing code where in yaml file I found two parameters mentioned below
name: "name"
in: "query"
description: "doing something"
x-phase-dataelem: "CONF//Y/N"
required: false
schema:
type: string
maxlength:15
name: "tame"
in: "header"
description: "doing something something"
x-phase-dataelem: "CONF//Y/N"
required: true
schema:
type: string
maxlength:15
am literally not able to understand these parameters
in: "query"
in: "header"
x-phase-dataelem: "CONF//Y/N"
I know that, these are some values which are being passed to client url to process, but not able to understand these parameters. what's significance of using these 3 parameters ?
can anyone help ?

This YAML snippet looks like a Swagger/OpenAPI contract. You can find more about OpenAPi and read its specification here - https://swagger.io/specification/
in describes the location of the HTTP parameter.
Quote from the OpenAPI specification:
There are four possible parameter locations specified by the in
field:
path - Used together with Path Templating, where the parameter value is actually part of the operation's URL. This does not include
the host or base path of the API. For example, in /items/{itemId}, the
path parameter is itemId.
query - Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
header - Custom headers that are expected as part of the request. Note that RFC7230 states header names are case insensitive.
cookie - Used to pass a specific cookie value to the API.
Regarding the x-phase-dataelem, it is a custom extension in your OpenAPI contract. It is used for providing some additional metadata/information/properties about the described items (including parameters).
Quote from the OpenAPI specification:
While the OpenAPI Specification tries to accommodate most use cases,
additional data can be added to extend the specification at certain
points.
The extensions properties are implemented as patterned fields that are always prefixed by x-, for example, x-internal-id. The value can be null, a primitive, an array or an object. Can have any valid JSON format value.

Related

How to use custom class in the swagger API

In my previous post
How to accept multiple query parameters with different parameter name in one class
I learned about passing the query parameters, and I also achieved it
But now the problem is I am in a swagger setup where I use codegen for generating API default code which provides me an interface using which I implement it into my controller layer and overrides those methods and add my logic
The problem is I have an internal api-doc file that generates a custom code, in that file how should I mention that I am using my own custom class for passing it to be used as a query parameter object? Currently, my api doc file looks like below. Problem with below file is I have to define each and every query parameter and as I learned in my previous stack article that we can wrap it into an class object. But my question here is how should I mention path to my custom class into this file.
/tasks:
get:
parameters:
- $ref: 'api-params.yaml#/name'
- $ref: 'api-params.yaml#/age'
- $ref: 'api-params.yaml#/credentials'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: 'api-resp.yaml#/someResponse'
"401":
description: "Unauthorized"
content: { }
"403":
description: "Forbidden"
content: { }
And also can we directly define a model using swagger? If yes how can we do that?
I mean I am using custom models for referring them to be used as request body and I usually mention them like below, but my question is can we use similar behaviour for queryParams also
schema:
$ref: '#/components/schemas/RquestBodyPayload'
but is the similar this is also allowed for query parameters ?

swagger 2.0 not validating enum in header

I am working on a project that uses Swagger 2.0 to generate an API interface which is then implemented in production code. There is a problem with a parameter that comes from the header.
There are 2 desired behaviors -
If a value is provided and does not match the enum, it should throw an error
If no value is provided, it should be given the default value of 'English'
Here is the code -
parameters:
language:
in: header
name: language
description: language the request will be processed in
type: string
default: English
enum: [English, Spanish, German, French]
required: false
However, the API accepts any value and does not provide a default value.
The generated code does not give any hint that it should be an enum. It does show the default value but did not provide it when I performed an integration test.
#ApiParam(value = "language the request will be processed in" , defaultValue="English") #RequestHeader(value="language", required=false) String language);
I found other similiar questions on here but no answers -
Swagger does not validate enum query parameter

How to customise the body type of response entity in OpenAPI?

I am working on a Spring project that allows users to download CSV files from an endpoint.
OpenAPI Generator is used for code generation.
According to the "Response That Returns a File" section of the documentation, the schema for the response can be defined as type: string with format: binary. The generated interface would then be something like:
CompletableFuture<ResponseEntity<org.springframework.core.io.Resource>> downloadFile().
How can we specify an alternative body type for ResponseEntity? (e.g. StreamingResponseBody described in this blog)
The OpenAPI Generator has a configuration option named typeMappings which allows you to change the default mapping of OpenApi primitive types (such as array, float, etc...) to the corresponding java class (java.util.List, Float, ...).
In your particular case, you could try to map the "binary" type to something different from "java.util.File".
The default mappings are defined here - see as from line 1464

pass variable to a method as a parameter

I have following code in my tml file:
<t:loop source="navItem.subPages" value="var:subPage">
<t:any element="li" class="prop:classForPageName">
<t:pagelink page="var:subPage">${getMenuPageName(var:subPage)}</t:pagelink>
</t:any>
</t:loop>
I have a problem to pass a variable var:subPage to method ${getMenuPageName(var:subPage)}, as this throws an exception:
Could not convert 'getMenuPageName(var:subPage)' into a component parameter binding: Error parsing property expression 'getMenuPageName(var:subPage)': line 1:15 no viable alternative at input '('.
You can't use binding prefixes (like var:) inside property expressions.
You may only use prefix in front of the expression to let Tapestry know how it should interpret the remainder (the part after the colon).
Refer to NBF grammar for property expressions to see what's allowed inside:
Tapestry Documentation > User Guide > Property Expressions.
Property expressions were created to support just very basic constructs. If you need more complex expressions you should create corresponding methods in your java class and refer to them using the prop: binding prefix.
Template expansions you've mentioned (${...}) work the same as parameter bindings:
Under the covers, expansions are the same as parameter bindings. The
default binding prefix for expansions is "prop:" (that is, the name of
a property or a property expression), but other binding prefixes are
useful, especially "message:" (to access a localized message from the
component's message catalog).

How are MessageBodyReaders used

Given something like:
e.g.
class User{
String name;
String someField1;
}
#Consumes("some/media-type")
class ResourceA{
public Response test(#FormParam("u") User u, #FormParam("f) String someField){
}
}
Couple of questions:
Will a single MessageBodyReader used to de-serialize User or will each field in user be de-serialized by a different reader?
Is #context required on any/all of these?
Is #FormParam required on the fields in the User class?
I'm trying to understand if the server will take the list of readers available and for each param in test, check if ANY of the readers can de-serialize that type. Or if the first reader which matches the media type consumed is expected to de-serialize all the params.
If the server is iterating through each parameter and for each parameter finding the most appropriate reader, it kind of makes sense that the input stream being passed to readFrom is the same instance, and each reader is advancing through the input stream. Is this the case or am I totally misunderstanding how the MessageBodyReader is meant to be used?
Have a look at this documentation on how entity providers are selected. In particular:
Procedure 7.2. MessageBodyReader Selection Algorithm
Obtain the media type of the request. If the request does not contain
a Content-Type header then use application/octet-stream media type.
Identify the Java type of the parameter whose value will be mapped
from the entity body. The Java type on the server is the type of the
entity parameter of the resource method. On the client it is the Class
passed to readFrom method.
Select the set of available MessageBodyReader providers that
support the media type of the request.
Iterate through the selected MessageBodyReader classes and,
utilizing their isReadable method, choose the first
MessageBodyReader provider that supports the desired combination of
Java type/media type/annotations parameters.
If Step 4 locates a suitable MessageBodyReader, then use its
readFrom method to map the entity body to the desired Java type.
Otherwise, the server runtime MUST generate a NotSupportedException
(HTTP 415 status code) and no entity and the client runtime MUST
generate an instance of ProcessingException.
#Context is not required and #FormParam does not need to be added to your bean - just to the REST resource method.
It appears it works how I suspected.
Looking at the source for RESTEasy, the MethodInjectorImpl class uses the same request instance which has an input stream. For each parameter the injector discovers the most appropriate reader.
The input stream is not touched and is advanced by each reader which parses a value from the request.

Categories