I want to document my Spring Boot Rest APIs with OpenAPI and swagger. The problem I have is that I have to add ApiResponse annotation for each possible response code and repeat that for every single API:
#Operation(summary = "Create new Address")
#ApiResponses(value = {
#ApiResponse(responseCode = "201", description = "New Address created", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = AddressResponse.class))
}),
#ApiResponse(responseCode = "400", description = "Invalid input supplied", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = ErrorResponse.class))
}),
#ApiResponse(responseCode = "401", description = "Unauthorized", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = ErrorResponse.class)),
}),
#ApiResponse(responseCode = "404", description = "Not Found", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = ErrorResponse.class)),
}),
#ApiResponse(responseCode = "409", description = "Conflict", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = ErrorResponse.class)),
}),
#ApiResponse(responseCode = "422", description = "Unprocessable Entity", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = ErrorResponse.class)),
}),
#ApiResponse(responseCode = "500", description = "Internal Server Error", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = ErrorResponse.class)),
}),
})
Is there a way to combine all ApiResponses for "400, 401, 404, 409, 422, 500 and default" together? Something like this:
#Operation(summary = "Create new Address")
#ApiResponses(value = {
#ApiResponse(responseCode = "201", description = "New Address created", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = AddressResponse.class))
}),
#ApiResponse(responseCode = "400,401,404,409,422,500,default", description = "Error Happened", content = {
#Content(mediaType = "application/json", schema = #Schema(implementation = ErrorResponse.class))
}),
})
short answer, No.
As stated in the openapi spec direct children of responses object are https statuses for each response. However you can use tags for grouping your operations (and not responses)
Related
I would like to set a variable only if a value is present.
My variables are:
variable "http_tcp_listeners" {
description = "aws_lb_listener"
type = map(any)
default = {
http = {
# load_balancer_arn = aws_lb.nlb_test.arn
port = "80"
protocol = "TCP"
action_type = "forward"
certificate_arn = ""
alpn_policy = ""
},
https = {
# load_balancer_arn = aws_lb.nlb_test.arn
port = "443"
protocol = "TLS"
action_type = "forward"
certificate_arn = "arn:aws:acm:us-east-1:b447fa7953be"
alpn_policy = "HTTP2Preferred"
}
}
}
In case http listener the string alpn_policy = each.value.alpn_policy should be absent. If the string is just empty alpn_policy = "" we will have got error Error: expected alpn_policy to be one of [HTTP1Only HTTP2Only HTTP2Optional HTTP2Preferred None], got
If we set any value we will have the error message that ALPN policy cannot be set for non secure listeners
I would like something like this. Pseudocode.
...
If val.alpn_policy != empty then
certificate_arn = try(each.value.certificate_arn, false)
alpn_policy = each.value.alpn_policy
default_action {
else
certificate_arn = try(each.value.certificate_arn, false)
default_action {
...
resource "aws_lb_listener" "frontend_http_tcp" {
for_each = var.http_tcp_listeners
load_balancer_arn = aws_lb.main.arn
port = each.value.port
protocol = each.value.protocol
certificate_arn = try(each.value.certificate_arn, false)
alpn_policy = each.value.alpn_policy
default_action {
type = each.value.action_type
target_group_arn = aws_lb_target_group.main[each.key].arn
}
depends_on = [
aws_lb.main,
aws_lb_target_group.main,
]
}
Thank #RafaP and #Marcin for the ideas. Finally, the code looks like this.
I have deleted unwanted variables in VAR and uses try Function alpn_policy= try(each.value.alpn_policy, null)
instead of
alpn_policy = lookup(var.https_listeners[count.index], "alpn_policy", null)
variable "http_tcp_listeners" {
description = "aws_lb_listener"
type = map(any)
default = {
http = {
port = "80"
protocol = "TCP"
action_type = "forward"
},
https = {
port = "443"
protocol = "TLS"
action_type = "forward"
certificate_arn = "arn:aws:acm:us-east-1:714154805721:certificate/c3be"
alpn_policy = "HTTP2Preferred"
}
}
}
resource "aws_lb_listener" "frontend_http_tcp" {
for_each = var.http_tcp_listeners
load_balancer_arn = aws_lb.main.arn
port = each.value.port
protocol = each.value.protocol
certificate_arn = try(each.value.certificate_arn, null)
alpn_policy = try(each.value.alpn_policy, null)
default_action {
type = each.value.action_type
target_group_arn = aws_lb_target_group.main[each.key].arn
}
depends_on = [
aws_lb.main,
aws_lb_target_group.main,
]
}
Dynamics 365 v8.2.2.
Why attributesMetadata is null? How can I get the entity attributes metadata list?
{
var req = new RetrieveEntityRequest {
LogicalName = "opportunity",
RetrieveAsIfPublished = true,
};
var resp = srv.Execute(req) as RetrieveEntityResponse;
var entityMetadata = resp.EntityMetadata;
var attributesMetadata = entityMetadata.Attributes; // null
}
You need to set EntityFilters in request like:
EntityFilters = EntityFilters.All
Or
EntityFilters = EntityFilters.Attributes
The complete snippet as follows:
RetrieveEntityRequest retrieveEntityRequest = new RetrieveEntityRequest
{
EntityFilters = EntityFilters.Attributes,
LogicalName = "opportunity"
};
RetrieveEntityResponse retrieveOpptyEntityResponse(RetrieveEntityResponse)service.Execute(retrieveEntityRequest);
EntityMetadata opptyEntity = retrieveOpptyEntityResponse.EntityMetadata;
By default, EntityFilters.Default only entity information will be retrieved, that’s why you have empty attribute list.
Read more
I am trying to upload an image to Amazon s3 bucket using vue js and laravel. But when i upload it the following exception appears :-
here's what i wrote in my controller to upload the file.
public function addProperty(Request $request)
{
$property = new Property;
$property->title = request('title');
$property->property_type = request('type');
$property->property_sub_type = request('subtype');
$property->address = request('address');
$property->property_index = 400;
#$property->save();
if ($request->hasFile('image')) {
$fileNameWithExtension = $request->file('image')- >getClientOriginalName();
$fileName = pathinfo($fileNameWithExtension, PATHINFO_FILENAME);
$extension = $request->file('image')->getClientOriginalExtension();
$fileNameStore =$fileName.'_'.time().'_'.'.'.$extension;
$disk = Storage::disk('s3');
$disk->put($fileNameStore, fopen($request->file('image'), 'r+'), 'public');
$profilePicImageUri = Storage::disk('s3')->url($fileNameStore);
dd($profilePicImageUri);
return $profilePicImageUri;
}
}
here's what i have done in Vue
onSubmit(){
let self = this;
let data = new FormData();
data.append('image',this.file);
data.append('title',this.propertyTitle);
data.append('type',this.type);
data.append('subtype',this.subtype);
data.append('lat',this.lat);
data.append('long',this.long);
data.append('address',this.address);
let config = {
headers:{
'Content-Type' : 'multipart/form-data'
}
}
axios.post(baseUrl + "api/admin/addproperty",data,config)
.then(function (response) {
console.log(response);
}).catch(function (error) {
{
console.log(error);
}
})
},
I have already setup my aws Configuration in env file. Here's my configuration
AWS_ACCESS_KEY_ID=XXXX
AWS_SECRET_ACCESS_KEY=XXX
AWS_DEFAULT_REGION=eu-central-1
AWS_BUCKET= php-laravel-upload
AWS_URL = https://php-laravel-upload.s3.eu-central-1.amazonaws.com
I don't understand what i am doing wrong. Can anyone help me?
try like that
if ($request->hasFile('image')) {
$fileInstance = $request->file('image');
$fileNameStore = $fileInstance->getClientOriginalName().'_'.time().'_.'.$fileInstance->getClientOriginalExtension();
Storage::disk('s3')->put($fileNameStore, $fileInstance, 'public');
$profilePicImageUri = Storage::disk('s3')->url($fileNameStore);
// dd($profilePicImageUri);
return $profilePicImageUri;
}
I tried to mke a request with GET and parameters. However, I got an exception for the WinPhone8.1 which meaned that GET was a violation protocol due to a content added in. So making a POST request is the solution.
Despite my searches, I'm still not able to set the content lenght property of my HttpWebRequest.. Why?
private static async void AsyncRequest(string url, string contentType, string methodType, int contentLenght, Action<Object, string> callback, Action<HttpStatusCode, JObject, Action<Object, string>> parserFunction)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = contentType;
request.Method = methodType;
request.Proxy = null;
if (methodType == Method.POST)
{
request.ContentLenght = "contentLenght";
request.Headers["content-length"] = "contentLenght";
request.Headers["Content-Length"] = "contentLenght";
request.Headers[HttpRequestHeader.ContentLength] = "contentLenght";
request.Headers["HttpRequestHeader.ContentLength"] = "contentLenght";
request.Content.Headers.ContentLength = "contentLenght";
...........
Nothing works ><
}
Debug.WriteLine("1");
Task<WebResponse> task = Task.Factory.FromAsync(
request.BeginGetResponse,
asyncResult => request.EndGetResponse(asyncResult),
(object)null);
Debug.WriteLine("2");
await task.ContinueWith(t => ReadStreamFromResponse(t.Result, callback, parserFunction));
}
Thank to jsonmcgraw for its answer on Xamarin Forums
If you want to make a POST request intead of GET request, then there is the two methods which can make you able to make GET/POST requests.
So, first, an async GET request.
public static async Task<string> MakeGetRequest(string url, string cookie)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
request.ContentType = "text/html";
request.Method = "GET";
request.Headers ["Cookie"] = cookie;
var response = await request.GetResponseAsync ();
var respStream = response.GetResponseStream();
respStream.Flush ();
using (StreamReader sr = new StreamReader (respStream)) {
//Need to return this response
string strContent = sr.ReadToEnd ();
respStream = null;
return strContent;
}
}
Sample usage:
public static async Task<MyModel[]> GetInfoAsync(int page, string searchString, string cookie)
{
string url = Constants.url + Constants.Path+
"page=" + page +
"&searchString=" + searchString;
string result = await WebControl.MakeGetRequest (url, cookie);
MyModel[] models = Newtonsoft.Json.JsonConvert.DeserializeObject<MyModel[]> (result);
return models;
}
Next, an async POST request
public static async Task<string> MakePostRequest (string url, string data, string cookie, bool isJson = true)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
if (isJson)
request.ContentType = "application/json";
else
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
request.Headers ["Cookie"] = cookie;
var stream = await request.GetRequestStreamAsync ();
using (var writer = new StreamWriter (stream)) {
writer.Write (data);
writer.Flush ();
writer.Dispose ();
}
var response = await request.GetResponseAsync ();
var respStream = response.GetResponseStream();
using (StreamReader sr = new StreamReader (respStream)) {
//Need to return this response
return sr.ReadToEnd();
}
}
Sample usage:
public static async Task<ResultModel> PostInfoAsync(int id, string cookie)
{
string data = "id=" + id;
//third param means that the content type is not json
string resp = await WebControl.MakePostRequest (Constants.url + Constants.Path, data, cookie, false);
ResultModel model;
try {
model = JsonConvert.DeserializeObject<ResultModel> (resp);
}
catch (Exception) {
model = new ResultModel{ isSuccess = false, Message = resp };
}
return model;
}
I need your help. I can parse correctly the graph.facebook.com/me/feed JSON, but i can't do it with graph.facebook.com/me/conversations. Can you please help me? this is how i get the last message from feed
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:nil];
NSLog(#"json %#", json);
NSDictionary *items = [json objectForKey:#"data"];
// NSDictionary *item = [items objectAtIndex:1];
NSLog(#"items %#", items);
NSMutableArray *story = [NSMutableArray array];
for (NSDictionary *item in items )
{
if([item objectForKey:#"message"] || [item objectForKey:#"message"] != nil || [[item objectForKey:#"message"] length]>0)
{
[story addObject:[item objectForKey:#"message"]];
}
else{
NSLog(#"no message");
}
}
NSLog(#"story %#", story);
NSString *lastMessage = [story objectAtIndex:0];
NSLog(#"lastmessage received is %#", lastMessage);
Can you please help me? Thanks
EDIT: I get this error in NSString *lastMessage = [story objectAtIndex:0];
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for
empty array'
* First throw call stack: (0x341fc2a3 0x3aede97f 0x34147b75 0xc3a1d 0x3add2d91 0x3c22c11f 0x3c22fecf 0x3c22fdc1 0x3c23091d 0x3c230ac1
0x3ae54a11 0x3ae548a4) libc++abi.dylib: terminate called throwing an
exception
NSLog from "items" is the following:
(
{
"can_reply" = 1;
id = "t_id.xx5719286166414";
"is_subscribed" = 1;
link = "http://www.facebook.com/messages/?action=read&tid=id.xx5719286166414";
"message_count" = 4;
messages = {
data = (
{
"created_time" = "2012-11-30T17:53:00+0000";
from = {
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
};
id = "m_msg.fe83b318fa94e6bbcc90a9a52fa4645b01";
message = "Questo \U00e8 un messaggio";
tags = {
data = (
{
name = inbox;
},
{
name = messenger;
},
{
name = read;
},
{
name = "source:mobile";
}
);
};
to = {
data = (
{
email = "100004765716168#facebook.com";
id = 100004765716168;
name = "AccountDevelopment Development";
},
{
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
}
);
};
},
{
"created_time" = "2012-11-29T11:49:00+0000";
from = {
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
};
id = "m_id.128631660627297";
message = "funziona?";
tags = {
data = (
{
name = inbox;
},
{
name = read;
},
{
name = "source:web";
}
);
};
to = {
data = (
{
email = "100004765716168#facebook.com";
id = 100004765716168;
name = "AccountDevelopment Development";
},
{
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
}
);
};
},
{
"created_time" = "2012-11-28T18:05:57+0000";
from = {
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
};
id = "m_id.141590452655798";
message = "prova messaggio";
tags = {
data = (
{
name = inbox;
},
{
name = read;
},
{
name = "source:web";
}
);
};
to = {
data = (
{
email = "100004765716168#facebook.com";
id = 100004765716168;
name = "AccountDevelopment Development";
},
{
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
}
);
};
},
{
"created_time" = "2012-11-28T18:04:50+0000";
from = {
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
};
id = "m_id.xx5719286166414";
message = "Ciao Francesco, come stai?";
tags = {
data = (
{
name = inbox;
},
{
name = read;
},
{
name = "source:web";
}
);
};
to = {
data = (
{
email = "100004765716168#facebook.com";
id = 100004765716168;
name = "AccountDevelopment Development";
},
{
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
}
);
};
}
);
paging = {
next = "https://graph.facebook.com/t_id.xx5719286166414/messages?access_token=BAABlotMxL1MBACbrnuvICOwBKjkw68ZBaqLOY2MVE6tga8xPmiF9VWH7RZAZCoZBDeSD29KWTzuze3xpjP7xb1kmfyw7VYtvGZC0E1gwgJthpZAoKoFXAYanGcBMb1qzO7SBAI3WPLcLAq7yAUpyF9NiHY0vIpsiGJZASx3eZCA83Lm18hpjmo0K97ZBSOiAoYeZCm2vYDgqq4S8jqOvZCvGZCZByNeg4ElNiSwZA1hHqdA6qrFAZDZD&limit=25&until=1354125890&__paging_token=m_id.xx5719286166414";
previous = "https://graph.facebook.com/t_id.xx5719286166414/messages?access_token=BAABlotMxL1MBACbrnuvICOwBKjkw68ZBaqLOY2MVE6tga8xPmiF9VWH7RZAZCoZBDeSD29KWTzuze3xpjP7xb1kmfyw7VYtvGZC0E1gwgJthpZAoKoFXAYanGcBMb1qzO7SBAI3WPLcLAq7yAUpyF9NiHY0vIpsiGJZASx3eZCA83Lm18hpjmo0K97ZBSOiAoYeZCm2vYDgqq4S8jqOvZCvGZCZByNeg4ElNiSwZA1hHqdA6qrFAZDZD&limit=25&since=1354297980&__paging_token=m_msg.fe83b318fa94e6bbcc90a9a52fa4645b01&__previous=1";
};
};
participants = {
data = (
{
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
},
{
email = "100004765716168#facebook.com";
id = 100004765716168;
name = "AccountDevelopment Development";
}
);
};
senders = {
data = (
{
email = "1367741936#facebook.com";
id = 1367741936;
name = " xxx xxx";
}
);
};
snippet = "Questo \U00e8 un messaggio";
tags = {
data = (
{
name = inbox;
},
{
name = read;
},
{
name = seen;
},
{
name = "source:web";
}
);
};
"updated_time" = "2012-11-30T17:53:00+0000";
}
)
You are missing a level in your accessors. The top level item in the JSON is messages, and that contains data. And then data is an array, not a dictionary. So you should change the first lines to this...
NSArray *messageGroups = [json objectForKey:#"data"];
NSDictionary* firstMessageGroup = [messageGroups objectAtIndex:0];
NSDictionary *messages = [firstMessageGroup objectForKey:#"messages"];
NSArray* items = [messages objectForKey#"data"];