Use an array as response model in AWS Gateway cdk - arrays

I'm trying to create a typescript aws cdk to build up an API Gateway with this own swagger documentation.
There is one simple endpoint returning a list of "Supplier", but we don't know how to specify this in the cdk.
Here the code:
export function CreateSupplierMethods(apigw: apigateway.Resource,restApiId: string, scope: cdk.Construct, api: apigateway.RestApi) {
let suppliers = apigw.addResource('suppliers')
let supplierModel = new apigateway.Model(scope, "supplier-model", {
modelName: "supplier",
restApi: api,
contentType: 'application/json',
schema: {
description: "Supplier data",
title: "Supplier",
properties: {
code: { type: apigateway.JsonSchemaType.STRING, minLength: 4, maxLength: 6},
name: { type: apigateway.JsonSchemaType.STRING, maxLength: 81},
}
},
})
let getSuppliers = suppliers.addMethod('GET', new apigateway.MockIntegration(), {
methodResponses: [{
statusCode: "200",
responseModels: {
"application/json": supplierModel,
}
},
{
statusCode: "401",
}]
})
}
As you can see, the GET has the supplierModel as output.
How can I say "returns a list of supplierModel"? I wish I can use this model for both list of supplier and single instances of supplier (like a GET method with id as input).
Is this possible? If yes, how?
Looking the generated json, I'm trying to have something like this:
But what I'm getting now is quite different:
How can I get a result like the first image?

You are creating a model and assigning it to the method.
Create an array of those models and then assign that array to the method.
let supplierModelArray = new apigateway.Model(scope, "supplier-model-array", {
modelName: "supplier-array",
restApi: api,
contentType: 'application/json',
schema: {
description: "Supplier data",
title: "Supplier",
type: apigateway.JsonSchemaType.ARRAY
items: {type: supplierModel}
},
})
And change the "application/json": supplierModel in api to "application/json": supplierModelArray

Related

Storing messages in new conversation collections; MongoDB

I'm a student working on a chat application for my internship, where I use socket.io.
Right now I am busy thinking of a good way to store the messages send in conversations.
As of now I do the following:
For each conversation between one user and another user, a new collection is made.
On every message sent, the message is stored in the according conversation collection in a single document.
The collections:
Where the document looks as follows:
Now I wonder if there is a good argument to be made to have just one collection "conversations", and store all the messages in multiple documents, where each conversation is a new document.
Creating a new collection for every message is very bad idea instead of that you use a simple schema as given below to store your messages
const conversation_schema = new Schema({
from: {
type: ObjectID,
ref: 'User'
},
to: {
type: ObjectID,
ref: 'User'
},
messageBody: { // body of the message(text body/ image blob/ video blob)
type: String,
},
messageType: { // type of the message(text, mp3, mp4, etc...)
type: String,
},
read: { // to boolean flag to mark whether the to user has read the message
type: Boolean,
default: false,
},
createdAt: { // when was this message goit created
type: Date,
default: new Date(),
},
});
you can fetch the conversation between the two users using the following query
conversations.find({
$or: [
{from: 'user1', TO: 'user2},
{from: 'user2', TO: 'user1},
],
}).populate({ path: 'to', model: User })
.populate({ path: 'from', model: User })
.sort({ createdAt: -1 })

Posting to mongoDb with ObjectId Many to one relationship

Mongoose/MongoDB Question
I have an Owners model containing basic profile data.
I have a secondary model: OwnersImages
e.g
{
owner: {
type: Schema.Types.ObjectId,
ref: 'Owners'
},
name: String,
imageUrl: String,
},
);
From the client I want to post the imageUrl and the name to the OwnersImages table.
e.g
let values = {
owner: this.state.user._id,
name: this.state.field,
imageUrl: this.state.url
}
axios.post(`${serverPath}/api/addFieldImage`, values)
However Im unsure how best to go about this, link it etc.
I can do a GET request on the Owners table to get the Owner data, but then posting this as part of the values to OwnerImages doesn't successfully link the two tables.
Do i need to just store a string reference to the Owner id in OwnerImages or is there a smarter way of doing this?
Or should I just post the string of the user Id to mongoose and then do a map to the Owner table from within there?
Tried to explain this best way I could but the eyes are tired so please ask if any confusion!
Many thanks
Without seeing your exact setup, I think you could modify this to fit your needs:
// In the Schema/Model files
const ownersSchema = Schema({
// other fields above...
images: [{ type: Schema.Types.ObjectId, ref: 'OwnersImages' }]
});
const ownersImagesSchema = Schema({
// other fields above...
owner: { type: Schema.Types.ObjectId, ref: 'Owners' },
});
// in the route-handler
Owners.findById(req.body.owner, async (err, owner) => {
const ownersImage = new OwnersImages(req.body);
owner.images.push(ownersImage._id);
await ownersImage.save();
await owner.save();
});
As a side-note, I think the Models generally have singular names, so Owner and OwnerImage. The collection will then automatically take on the plural form. Just food for thought.
When you want to load these, you can link them with populate(). Consider loading all of the OwnersImages associated with an Owners in some route-handler where the /:id param is the Owners id:
Owners
.findOne({ _id: req.params.id })
.populate('images')
.exec(function (err, images) {
if (err) return handleError(err);
// do something with the images...
});

React Relay fetch list

I need to fetch list
I have Schema
export const Schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: {
activities: {
name: 'Activities',
type: new GraphQLList(activityType),
resolve: (root, args, { rootValue }) => {
return User.findById(rootValue.req.user.id)
.populate('activities')
.then((user) => user.activities);
},
},
When I do graphql request using curl and sends
query ActivitiesQuery {
activities {
name
}
}
it gives me
{
"data": {
"activities": [
{
"name": "Eat"
}
]
}
}
Can somebody give me example how can I fetch it using relay ? because all the examples give object and then list like Store: { teas: [...
activities is an example of a plural non-identifying field. It is plural in the sense that it returns a list of things, and non-identifying in the sense that the individual elements of that list are not identified by global IDs.
Relay does not support plural non-identifying fields at the root, but support is coming. Follow along at https://github.com/facebook/relay/issues/112

Removing an object from an array inside a Collection

I'm using the following methods to push and pull objects into the "following" array, which is a property on each user's profile.
Meteor.users.update({ _id: this.userId }, { $push: {
"profile.following": { _id: _id, service: service, type: type }}
});
// I specify that it is required to match these two properties to remove an object
Meteor.users.update({ _id: this.userId }, { $pull: {
"profile.following": { service: service, type: type } }
});
This approach does work, it removes the object, but I always get this error:
Exception while simulating the effect of invoking 'unfollow' Error: documentMatches needs a document {stack: (...), message: "documentMatches needs a document"} Error: documentMatches needs a document
at Error (native)
at _.extend.documentMatches (http://localhost:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:1341:13)
at MODIFIERS.$pull (http://localhost:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:3414:24)
at http://localhost:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:3124:9
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:164:22)
at http://localhost:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:3105:9
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:164:22)
at Function.LocalCollection._modify (http://localhost:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:3098:7)
at LocalCollection._modifyAndNotify (http://localhost:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:848:19)
at http://localhost:3000/packages/minimongo.js?e8806aa7782b729b2517ebc0cd10b321667f1427:765:12
I'm not sure if this is a bug with Meteor or if I maybe I'm not writing the query correctly.
Apparent $elemMatch is needed to do this:
Meteor.users.update({ _id: this.userId }, { $pull: {
"profile.following": { $elemMatch: { service: service, type: type } } }
});

Firebase with Backbone and One to Many Association

So I am attempting to build a one on one chat app with firebase using marionette and backbone. I'm also using the Firebase Backbone bindings. I want there to be many users, each user has many conversation, and each conversation has many messages. Here's how my data looks:
users: {
'user-id-1': {
email: 'test#whatever.com',
conversations: {
'conversation-id-1': true,
'conversation-id-2': true
}
},
'user-id-2': {
email: 'another#email.com',
conversations: {
'conversation-id-1': true,
}
},
'user-id-3': {
email: 'a-third#email.com',
conversations: {
'conversation-id-2': true,
}
}
}
conversations: {
'conversation-id-1': {
sender: 'user-id-1',
receiver: 'user-id-2',
messages: {
'message-id-1': true,
'message-id-2': true
}
},
'conversation-id-2': {
sender: 'user-id-1',
receiver: 'user-id-3',
messages: {
'message-id-3': true,
'message-id-4': true,
'message-id-5': true,
}
}
}
messages: {
'message-id-1': {
sender: 'user-id-1'
body: 'A message'
},
'message-id-2': {
sender: 'user-id-2'
body: 'A response'
},
'message-id-3': {
sender: 'user-id-1'
body: 'An inital message'
},
'message-id-4': {
sender: 'user-id-3'
body: 'Another response'
},
'message-id-5': {
sender: 'user-id-1'
body: 'Goodbye'
},
}
What you can see from this:
User-1 has two different conversations going, each with User-2 and User-3
On a really basic level I am able to fetch all the conversations from the user with a function like so:
class Entities.User extends Backbone.Firebase.Model
urlRoot: 'https://my-app.firebaseio.com/users'
conversations: ->
conversations = new Firebase('https://my-app.firebaseio.com/conversations')
#firebase.child('conversations').on 'child_added', (snap) =>
console.log snap.key()
conversations(snap.key()).once 'value', (value) =>
console.log value.val()
undefined
This will log all of the conversations out when they are retrieved by firebase.
The problems are:
a) There's no real way for me to use a Backbone.Collection here to fetch just this users conversations, let alone the messages for that conversation, is there? I need a collection to pass to Marionettes CollectionView
b) This just seems really messy in general.
Should I be structuring my data differently? I realize there's improvements that could be made to at least the way I am collecting the conversations so I could get an array.
What am I doing wrong? Any advice would be much appreciated.

Resources