Akka HTTP, Spray Json and Option Fields Failing as Required - scala

I have a case class:
case class OpcTagPlaybook(name: String, tags: Seq[OpcTagAtTime], looped: Boolean, enabled: Option[String])
With an optional enabled field that will contain a date.
Spray Json describes encoding/decoding:
implicit val opcTagPlaybookFormat = jsonFormat4(OpcTagPlaybook)
And a route in akka http:
post {
entity(as[OpcTagPlaybook]) { playbook =>
val playbookCreated: Future[_] =
(opcTagPlaybookActor ? UpsertPlaybook(playbook))
onSuccess(playbookCreated) { _ =>
log.info("Created playbook [{}]", playbook.name)
complete((StatusCodes.Created, "ok"))
}
}
})
For some reason posting without the createdAt field fails:
Posting:
{"name": "test1",
"tags":[{"offset": 100, "tag": "hello", "value": "yo"}],
"looped": true
}
Fails:
The request content was malformed:
Object is missing required member 'enabled'
And if I post created it gives me another error:
{"name": "test1",
"tags":[{"offset": 100, "tag": "hello", "value": "yo"}],
"looped": true,
"enabled": "2018-08-08"
}
gives
The request content was malformed:
spray.json.JsString cannot be cast to scala.Option
I'm assuming this is some interplay between akka http and so I'm going to just deal with the input more manually but I'd just like to understand what I'm doing wrong here.

Related

RDSDataService not recognizing `typeHint` in `batchExecuteStatement` method

I'm trying to run the batchExecuteStatement method. For some kind of reason, passing as parameter (besides the sql string and the resource configuration)
[
[
{ name: 'id', value: { stringValue: 'uuidString' }, typeHint: 'UUID' },
{ name: 'meta', value: { stringValue: '{}' }, typeHint: 'JSON' }
]
]
results in the method throwing this exception UnexpectedParameter: Unexpected key 'typeHint' found in params.parameterSets[0][0].
I do not understand why, since the query parameters look the same as in the aws doc.
The query is a simple INSERT INTO alarms_log VALUES(:id, :meta); statement
Source doc link: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RDSDataService.html#batchExecuteStatement-property

AWS AppSync not displaying custom error properties with in Lambda Resolver ResponseMappingTemplate

We are trying to use custom error status codes with GraphQL so that our upstream services can better utilize the errors thrown.
We have a simple error class that extends the base Error class to include a status code:
export class ErrorWithStatusCode extends Error {
public statusCode: number;
constructor({
message,
name,
statusCode,
}: {
message: string;
name: string;
statusCode: number;
}) {
super(message);
this.name = name;
this.statusCode = statusCode;
}
}
export class BadRequestError extends ErrorWithStatusCode {
constructor(message: string) {
super({
message,
name: `BAD_REQUEST`,
statusCode: 400,
});
}
}
And then we throw that error in our code like so:
if (existingResource) {
throw new BadRequestError('An account with the email address already exists');
}
Inside our logs we see the Lambda invoke error:
2022-04-29T13:42:56.530Z 0e1688ac-89f1-46a7-b592-d6aeceb83fd7 ERROR Invoke Error
{
"errorType": "BAD_REQUEST",
"errorMessage": "An account with the email address already exists",
"name": "BAD_REQUEST",
"statusCode": 400,
"stack": [
"BAD_REQUEST: An account with the email address already exists",
" at Runtime.main [as handler] (/var/task/index.js:26908:19)",
" at processTicksAndRejections (internal/process/task_queues.js:95:5)"
]
}
Then in our VTL template, we just associate all properties outside of name and message to the custom errorInfo object as described here
$util.error(String, String, Object, Object)
Throws a custom error. This can be used in request or response mapping templates if the
template detects an error with the request or with the invocation
result. Additionally, an errorType field, a data field, and a
errorInfo field can be specified. The data value will be added to the
corresponding error block inside errors in the GraphQL response. Note:
data will be filtered based on the query selection set. The errorInfo
value will be added to the corresponding error block inside errors in
the GraphQL response. Note: errorInfo will NOT be filtered based on
the query selection set.
#if (!$util.isNull($ctx.error))
$utils.error($ctx.error.errorMessage, $ctx.error.name, $ctx.result, $ctx.error)
#end
$utils.toJson($ctx.result)
But when we get the error back from AppSync (using the console), we do not have any additional error properties:
{
"data": null,
"errors": [
{
"path": [
"createResource"
],
"data": null,
"errorType": null,
"errorInfo": {
"message": "An account with the email address already exists",
"type": "Lambda:Unhandled"
},
"locations": [
{
"line": 2,
"column": 5,
"sourceName": null
}
],
"message": "A custom error was thrown from a mapping template."
}
]
}

insomnia error: using tabs can lead to unpredictable results

i have documentation api that using insomnia designer and in the last 12000 lines i hadnt error like this
in all jsons as body or result this error may occurred
requestBody:
content:
application/json:
schema: # Request body contents
type: object
example:
{
"type": "national_card",
"data": "",
"mimetype": "image/jpeg"
}
in my case just need to remote a space here

REST API PATCH - update a specific value in an object

In a config file, I've got several vars.
{
"key1": "aaa",
"key2": {"smallkey1": "bbb", "smallkey2": "ccc"}
}
I need to update smallkey2 value, through a patch request (API obligation).
const updateConfigVar = (finaltarget, newdata) => {
HTTP.call( 'PATCH', 'https://api.xxx.com/apps/', {
headers: {
"Content-Type": "application/json"
},
data: {
[finaltarget]: newdata,
}
})
}
If I call updateConfigVar('key2', 'ddd'), I get:
{
"key1": "aaa",
"key2": "ddd"
}
But how to replace not the all key2 object but only the value of smallkey2 inside the key2 object.
So how to get:
{
"key1": "aaa",
"key2": {"smallkey1": "bbb", "smallkey2": "ddd"}
}
But how to replace not the all key2 object but only the value of smallkey2 inside the key2 object.
Normally, if we are using HTTP Patch to communicate a change to the server
The set of changes is represented in a format called a "patch document" identified by a media type.
You probably don't want to be using application/json as your media type, because the processing rules for JSON aren't specific to patching. A better bet would be to use either application/json-patch+json (described by RFC 6902) or application/merge-patch+json (described by RFC 7386).
Each of these has their own specific semantics for describing an edit to a nested key.

Unable to Test POST request In Scala HTTP Akka

Although the problem seems to be easy, but I am unable to get a OK 200 response while trying to register an Instance.
def register(InstanceString: String) : server.Route = {
post
{
log.debug(s"POST /register has been called, parameter is: $InstanceString")
try {
val paramInstance : Instance = InstanceString.parseJson.convertTo[Instance](instanceFormat)
handler.handleRegister(paramInstance) match {
case Success(id) =>
complete{id.toString}
}}}
Above is the method that executes the request.
Following is its API configuration:
paths:
/register:
post:
tags:
- Basic Operations
summary: Register a new instance at the registry
operationId: addInstance
parameters:
- in: body
name: InstanceToRegister
required: true
schema:
$ref: '#/definitions/Instance'
responses:
'200':
description: The ID of the registered instance
schema:
type: integer
format: int64
example: 42
Following is the test case that I am trying to execute but I get 400 Bad Request did not equal 200 OK.
"The Server" should {
"Successfully Register" in {
Post("/register", HttpEntity(ContentTypes.`application/json`,"""{"InstanceString":"hallo"}""")) ~> Route.seal(routes) ~> check {
assert(status === StatusCodes.OK)
Try this:
Post("/register", requestBody.toJson).withHeaders("if Any") ~> Route.seal(routes) ~> check {
status shouldBe StatusCodes.OK
}
I can see that you have Json reader for your request body, so use Json writer like this new InstanceString("hello").toJson you get request body.
I see that your your request content type is application/json and you are passing String.