How do I reference one model from another model using aws API Gateway - amazon-web-services

Say I have a Model:
"Pet":{
"type": "object"
"properties": {
"name":{"type":"integer"},
"age":{"type":"integer"}
}
}
And another model:
"Human":{
"type": "object"
"properties": {
"name":{"type":"integer"},
"age":{"type":"integer"},
"pets":{
"type":"array"
"items": {
<This is where my question is>
}
}
}
}
How can I reference the Pet model in my human model?
With swagger I was able to say:
"$ref": "#/definitions/Pet"
but API Gateway seems to not allow it.

If you mean reference model outside swagger, you can do that by specifying the model with an absolute url like below
{"type":"array","items":{"$ref":"https://apigateway.amazonaws.com/restapis/<rest_api_id>/models/Pet"}}
For swagger, this example from open api specification shows how to reference models within swagger - https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore.json
"Pets": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
Note that api gateway does not support 'default' response, so if you are trying to import the above petstore.json example, you need to remove the "default" fields.

If you just want single values (not arrays), this works:
..
"properties": {
"id": {
"$ref": "https://apigateway.amazonaws.com/restapis/abcd1234/models/UserId"
},
..
(It would be nice if this could be a relative URL rather than absolute, but I haven't found any mention of how to do this yet)

Related

Loopback 3 Queries not returning expected results for MySQL data field

I have a content model that looks like:
{
"name": "content",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"id": {
"type": "number"
},
"url": {
"type": "string",
"required": false
},
"data": {
"type": "Object",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [
{
"accessType": "WRITE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
},
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
],
"methods": {}
Example of this data in MySQL looks like this:
I've tried querying this data both with REST and the Node API and haven't been able to query by any of the nested object fields inside of the "data" database field. A few examples that don't work:
contentModel.findOne({ where: { "data.url": url } }, function (
err,
content
) {
if (err) {
console.log(err);
}
console.log("find:", content);
});
const filter = encodeURI(`{"where":{"systemid":"${contentType}"}}`);
let url = `${apiUrl}contentTypes?filter=${filter}`;
let contentTypeRecord = await this.getAxios().get(url);
I've also tried many queries in the loopback swagger ui. I usually get no results or it returns all the content records.
The above data access attempts do however work if I have the same data setup in MongoDb.
What am I doing wrong? Loopback should presumably be parsing the object in the data field and allowing me to filter on it.
AFAIK, LoopBack does not support query filters on nested properties. According to this comment, there is a limited support in PostgreSQL and MongoDB connectors:
#michelgokan as you'll see from the thread:
There is some support in postgres connector
Mongo also has some basic support (only for dot nested properties)
Further support isn't going to be added to other RDB connectors as loopback 3 is in LTS and no longer accepting new feature PRs
Loopback 3 ends LTS at the end of 2019 so it's even less likely to be added.
Options are:
Write the custom SQL yourself as a custom endpoint
Create an alternate connector for something like Knex or Bookshelf that has support (big job)
Do the filtering in memory
Use json for the nested data to use dot queries in something like mongo or postgres
Look at migrating to loopback next which may add support in the future
It seems that MySQL supports querying of JSON data, see docs for JSON_CONTAINS, thus it should be possible to implement this feature in loopback-connector-mysql. Feel free to open an issue in https://github.com/strongloop/loopback-connector-mysql/issues. A pull request would be even better! ❤️

multipart boundary not found - aws api gateway

I have created AWS API-Gateway and I am trying to upload an image using Postman but I received an error of Multipart: boundary not found.
I have tried below solution for this issue whereas I created model for API as follows:
Model name: fileupload
Content type: image/png
Model schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "UserAccountUpdate",
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"avatar": { "type": "string" },
"username": { "type": "string" }
}
}
}
}
But, this didn't worked.
I expect my image to get uploaded but it receives an error of Multipart: boundary not found.. Please Help me to resolve this issue, Thanks.
Go to the API Gateway settings tab for your API and add "multipart/form-data" to the "binary media types" section:
You have to use HTTP Proxy integration and for Content Handling , choose Passthrough.

Native way of view apigateway documentation in browser

I have an public AWS apigateway created providing a swagger file.
To document the API I have added to the swagger the following section:
"x-amazon-apigateway-documentation": {
"documentationParts": [
{
"location": {
"type": "API"
},
"properties": {
"description": "This is the API description"
}
},
{
"location": {
"type": "METHOD",
"method": "GET",
"path": "/foo/{bar}"
},
"properties": {
"description": "This is the method description"
}
}
]
}
Then I have published the documentation version 1.0 through AWS console.
Reached this point I want to give anyone the URL of my API documentation that ideally should be rendered in the browser in a nice way.
But, checking AWS docs regarding apigateway documentation I only find one way to access to it, that is using another AWS provided API:
http://apigateway.eu-central1.amazonaws.com/restapis/TheIdOfMyApiGateway/documentation/parts
Additionally, I should set some access keys in the request to retrieve it, making impossible for one agnostic user to simply view it in the browser setting no additional headers in the request.
Is there any way to achieve my aim?

ApiGateway CloudFormation without lambda

I am trying to create a template so that when i call api/divide/inputvalue, The api sends back response from DynamoDB which corresponds to inputvalue mapping.
Its pretty straight forward since i am fetching value directly from db without any business logic hence I don't need any lambda. But all the examples that I google or all tutorials they are using lambdas and i am now lost that how can i make it working without lambda
This is what I have so far. There is bug in this template right now since I haven't provided Uri in ApiGateway::Method. Which is what I am currently stuck at.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"Deployment": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": { "Ref": "restApiName" },
"Description": "First Deployment",
"StageName": "StagingStage"
},
"DependsOn" : ["restApiMethod"]
},
"restApiMethod": {
"Type": "AWS::ApiGateway::Method",
"Properties": {
"AuthorizationType": "NONE",
"HttpMethod": "GET",
"ResourceId": {"Ref": "apiRestResource"},
"RestApiId": {"Ref": "restApiName"},
"Integration": {
"Type": "AWS",
"IntegrationHttpMethod": "GET",
"IntegrationResponses": [{"StatusCode": 200}],
"Uri": { "Fn::Sub":"arn.aws.apigateway:${AWS::Region}:dynamodb:action/${restApiName.Arn}"}
},
"MethodResponses": [{"StatusCode": 200}]
},
"DependsOn": ["apiRestResource"]
},
"apiRestResource": {
"Type": "AWS::ApiGateway::Resource",
"Properties": {
"RestApiId": {"Ref": "restApiName"},
"ParentId": {
"Fn::GetAtt": ["restApiName","RootResourceId"]
},
"PathPart": "divide"
},
"DependsOn": ["restApiName"]
},
"restApiName": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"Name": "CalculationApi"
}
}
}
}
According to the documentation, the Uri property is structured as follows for AWS service-proxy integration types:
If you specify AWS for the Type property, specify an AWS service that follows the form: arn:aws:apigateway:region:subdomain.service|service:path|action/service_api. For example, a Lambda function URI follows the form: arn:aws:apigateway:region:lambda:path/path. The path is usually in the form /2015-03-31/functions/LambdaFunctionARN/invocations. For more information, see the uri property of the Integration resource in the Amazon API Gateway REST API Reference.
The uri API Gateway property reference provides more details:
For AWS integrations, the URI should be of the form arn:aws:apigateway:{region}:{subdomain.service|service}:{path|action}/{service_api}. Region, subdomain and service are used to determine the right endpoint. For AWS services that use the Action= query string parameter, service_api should be a valid action for the desired service. For RESTful AWS service APIs, path is used to indicate that the remaining substring in the URI should be treated as the path to the resource, including the initial /.
For an AWS service proxy to the dynamodb service calling the Query Action, the Uri should be something like this (using the YAML short-form of Fn::Sub to insert a Ref for the current AWS region):
!Sub "arn:aws:apigateway:${AWS::Region}:dynamodb:action/Query"
As for your broader use-case of using API Gateway to access DynamoDB without using Lambda functions, refer to Andrew Baird's tutorial blog post, "Using Amazon API Gateway as a Proxy for DynamoDB", and translate the specified Management Console steps to corresponding CloudFormation template resources.

Conflict in type inflection between EmberData and Django REST framework

EmberData is POSTing:
{
"data": {
"attributes": {
"name": "The project name",
"description": "The project description",
"price": 123
},
"relationships": {
"onwer": {
"data": null
}
},
"type": "projects"
}
}
And Django (drf I guess) is complaining with a 409 Conflict:
{
"errors": {
"detail": "The resource object's type (projects) is not the type that constitute the collection represented by the endpoint (project)."
}
}
Apparently the JSONApi spec does not enforce an inflection rule. How can I tell drf to accept plurals for the type?
There is a config parameter:
JSON_API_PLURALIZE_RELATION_TYPE = True
You could also explicitly set the resource name:
class CategoryViewSet(viewsets.ModelViewSet):
resource_name = 'categories'
...