{Method: POST, RequestUri: 'https://cmpanydynamicsurl.com/api/data/v8.2/tasks', Version: 1.1, Content: System.Net.Http.StringContent,
Headers:
{
OData-MaxVersion: 4.0
OData-Version: 4.0
Accept: application/json
Content-Type: application/json; charset=utf-8
Content-Length: 162
}}
Using the above request, I am trying to create a task against an account using Dynamics API post action.
Json Model being sent -
{
"subject":"NEW TEST TASK FOR ACCOUNT",
"_regardingobjectid_value#odata.bind":"/accounts(08b582ad-4e2f-e711-8101-5065f38a4a21)"
}
I am receiving this error message and have had no luck with searching the internet?
A property '_regardingobjectid_value' which only has property
annotations in the payload but no property value is declared to be of
type 'Edm.Guid'. In OData, only navigation properties and named
streams can be represented as properties without values.
The correct payload is
{
"subject": "NEW TEST TASK FOR ACCOUNT",
"regardingobjectid_account#odata.bind": "/accounts(08b582ad-4e2f-e711-8101-5065f38a4a21)"
}
You have to tell somehow to which object type you are binding, because regardingobjectid has mutliple types, and every type has its own separate relationship (in this case regardingobjectid_account). You are trying to bind value to a plain "Guid" property (because "_regardingobjectid_value" is a "Guid") but such property should be assigned exactly the same as you are doing with subject, so simply "_regardingobjectid_value": "08b582ad-4e2f-e711-8101-5065f38a4a21" but this will not work as you did not provide the type of entity.
Related
We are developing our microservices using Spring Boot and OpenAPI.
Each endpoint could possibly return many business exceptions (an errorCode) and their HTTP Status Codes are all the same (say 400).
Below is a pseudo code of one of the endpoints:
#RestController
#RequestMapping("/services")
public interface MyRestController {
#PostMapping("/service1")
HttpResponse executeService(HttpRequest request)
throws FirstBusinessException, SecondBusinessException;
}
And one of the following HTTP Responses would be returned, depending on the exception which occurred:
{
"errorCode": "FirstBusinessException",
"message": "A simple message for FirstBusinessException",
"errorParams": {
"key1": "value1",
"key2": "value2"
}
}
{
"errorCode": "SecondBusinessException",
"message": "A simple message for SecondBusinessException",
"errorParams": {
"key1": "value1",
"key2": "value2"
}
}
Status Code in both of the HTTP Header Responses are 400
We want to present it in our OpenAPI documentation, as it is important to us to tell our clients about each possible error of each endpoint.
Currently our workaround solution is documenting a list of all possible exceptions of the endpoint in its description.
Now I have following questions:
Is there any better (more standard) solution to this workaround?
(I would appreciate if you could demonstrate it with springdoc-openapi way of doing it)
I've also seen anyOf/oneOf feature that has been added since OpenAPI V3, but it requires different schemas. Should we really use different schemas for our exceptions (Instead of having a single one with for example errorCode, message, and errorParam fields, like above) ?
I believe what you are looking for is Spring's #ControllerAdvice. Something like this
#ControllerAdvice
public RestExceptionHandler {
#ExceptionHandler(FirstBusinessException.class)
public HttpResponse handleFirstBusinessException(FirstBusinessException ex, HttpRequest request) {
... do logic and return response
}
#ExceptionHandler(SecondBusinessException.class)
public HttpResponse handleSecondBusinessException(SecondBusinessException ex, HttpRequest request) {
... do logic and return response
}
}
This allows you to return the same HttpStatus for both errors, but a custom error message and/or response entity for each.
Then, in your openApi documentation, you can set it up like this
'400':
description: You have made an invalid request
content:
application/json:
schema:
oneOf:
- $ref: "#/components/schemas/ExceptionOne"
- $ref: "#/components/schemas/ExceptionTwo"
examples:
Exception One:
value:
Exception: invalid Id Provided
Provided ID: My ID 1
Message: don't do that
Exception two:
value:
Exception: incomplete request
message: missing one or more fields within your json request
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
When you provide multiple examples, this provides a drop down in your ui (I'm using swagger here) to show your users what the various responses may look like.
You can use these responses and their titles to better explain. For example, instead of calling it ExceptionOne you could call it Missing ID, or Duplicate ID.
If this doesn't work for you, another option is to make use of markdown syntax in your description to make your description more robust. For example:
description: |
# You have made an invalid request
## Exceptions contained here include:
1. Bad ID
2. Your json failed validation
3. You can't follow instructions
| exception | fix |
| --- | --- |
|badId | fix ID|
| failed validation | read validation error message |
| can't follow instructions | read better |
---
If these are in error, contact us:</br>
**phone**: 555-555-5555 </br>
**email**: us#help.com
Have a nice day.
will render as
I need to pass query string parameters calling a WSO2 api gateway that calls an AWS lambda function.
I created the following lambda function in NodeJS in AWS:
exports.handler = async (event, context) => {
return {
statusCode: 200,
body: JSON.stringify({
incoming:JSON.parse(event),
date: new Date(),
context: JSON.parse(context)
}),
};
};
Then I:
created a new API in wso2 publisher portal
added an endpoint of type lambda
configured a resource getTest for GET
added a query parameter parameter to the GET resource
When I call my API here is the result:
curl -X GET "https://localhost:8243/lambda/1/getTest?parameter=myValue" -H "accept: */*" -H "Authorization: Basic YWRtaW46YWRtaW4="
{
"statusCode":200,
"body":"{\"incoming\":{},\"date\":\"2021-06-22T08:09:36.027Z\",\"context\":{\"callbackWaitsForEmptyEventLoop\":true,\"functionVersion\":\"$LATEST\",\"functionName\":\"wso2get\",\"memoryLimitInMB\":\"128\",\"logGroupName\":\"/aws/lambda/wso2get\",\"logStreamName\":\"2021/06/22/[$LATEST]90a7f95746c644a7a5cc61ec8648228e\",\"invokedFunctionArn\":\"arn:aws:lambda:eu-west-1:659641230079:function:wso2get\",\"awsRequestId\":\"4e271442-6209-47d9-ab0c-277c6535b8bd\"}}"
}
How can I retrieve the parameter with value myValue in the lambda function?
You have to define you OpenAPI definition with this two kind of parameters:
Path Parameter
Query Parameter
I'll use wso2apim 2.6.0 and OpenAPI 2.0 definition...
Go to the /publisher and "Add a new API" with the "Design a New REST API"
Add a name , a contest ( ex. /mylambda ), and so on.
In the "API Definition" include a URL Pattern like
"/{id}/getTest" and check de GET method. Automatically a "Path parameter" is added with name "id".
Then add a new parameter named "parameter"
Save and in the implementation, set the "Endpoints" set the URL to:
"https://localhost:8243/lambda"
And that's all.
This is fixed in the latest pack. You can send path/query/header parameters, http method, and path along with the payload to Lambda. Make sure you define the parameter names at resource creation time as in 8.b.iii in [1]. Following is the format of the event object which Lambda receives.
{
"headers": {},
"pathParameters": {},
"queryStringParameters": {},
"body": {},
"httpMethod": "",
"path": ""
}
Note that, to enable param mapping for earlier versions, you have to put following config to deployment.toml file.
[apim.lambda_mediator_config]
pass_request_params = true
[1] https://apim.docs.wso2.com/en/latest/design/create-api/create-rest-api/create-a-rest-api/
What I want to do is add validation to the schema response from a fastify route.
Following the documentation from Fastify here we can see this
Ajv for the validation of a request
fast-json-stringify for the serialization of a response's body
Related to improve and add validations for a response, what I want to do is check the schema when I send a response.
fast-json-stringify support different options, included format, but if you read the documentation, they said that they support JSON schema. Jsonschema has support for email format, that you can see here as a built-in format but when I try to use it on Fastify, like this:
{
response: {
200: {
type: 'object',
required: ['email'],
properties: {
email: {
type: 'string',
format: 'email',
}
}
}
}
}
And try to return ad response this
reply.code(200).send({ email: 'test' })
The only validation that I can do is when I set the type to integer and try to return a string.
Did you know if it's possible to use ajv-formats with fast-json-stringify to add validation to the response schema and use the formats from ajv and add new ones?
Many thanks in advance!
fast-json-stringify does the serialization, not the validation.
The json schema provided to it will be used to serialize only the properties declared and some type checking like integer or arrays.
the enum keyword is not supported
the format keyword is supported only for the dates as documented:
To reach your goal, you should use this plugin: fastify-response-validation that will add a validation step of your response body before the serialization process.
Django and Django Rest Framework is not sensing the array in the following JSON object:
{
"datum":
[
{'proposed':'20/sep/2018', "pk":"475"},
{'proposed':'20/sep/2018', "pk":"517"}
]
}
When I do a print(request.data) this is the output:
<QueryDict: {'{"datum":[{"proposed_submission_date":"20/Sep/2018","pk":"475"},{"proposed_submission_date":"20/Sep/2018","pk":"512"}]}': ['']}>
and when I do a print(request.data.keys())I get:
{"datum":[{"proposed_submission_date":"20/Sep/2018","pk":"475"},{"proposed_submission_date":"20/Sep/2018","pk":"512"}]}
You can see that its taking the json string as the key, and not assigning "datum" as the key.
Do I need to do something else with the JSON string?
I'm doing an AJAX PUT to the Django rest framework backend.
the fact that you see a QueryDict rather than just a dict is a sign that you sent your data as application/x-www-form-urlencoded or multipart/form-data.
Ensure you send the request with a application/json content type and it should be just fine.
I'm using Apiary to mock out a new API.
I'm trying to avoid having to write out all the JSON responses over and over again. If I do that using a + Attributes(user) then it will auto generate a bunch of attributes blocks in the machine panel, which is super confusing in my mind (especially when you have multiple responses).
The resulting documentation looks way better if you write out the JSON request/response blocks manually.
Is there a way to store Request/Response objects as a Data Structure? Maybe a Model perhaps?
I'd love to be able to do something like this:
## Users [/auth]
A user object contains the these attributes.
+ Attributes (user) <!-- I like this here -->
### Refresh a token for a user [POST /auth/refresh]
+ Request (application/json)
+ Headers
Authorization: Bearer jsonWebToken
+ Response 200 (application/json)
+ Body
{
"data": [
(user) <!-- I wish this was the user data structure as JSON -->
],
"meta": {
"access_token": "jsonWebToken",
"token_type": "Bearer",
"expires_in": 3600
}
}
# Data Structures
## user (object)
+ id: 123 (number)
+ email: drew#funkhaus.us
Note: The user object is 30 attributes long in real life.
Unfortunately that's not a supported scenario, you can't but data structures into your JSON payloads.
So if I understand correctly - using Attributes is fine but you would like hide them in documentation. Could you confirm that?