I'm struggling with the typing of my query params in NestJs, I have a route like this and I want to be able to filter my result with all the keys of my datamining entities. I did this and it's working but I can't find a way to make it appear in my swagger:
#Controller('datamining')
export class DataminingController {
#Get('short')
#ApiQuery({ required: false, type: DataminingShort }) // <== how to type this ? Obviously this one is not working.
findAll(#Query() options?: Partial<DataminingShort>) { // <== DataminingShort is an entity class for typeOrm
return this.dataminingShortService.findAll(options);
}
}
I want to avoid doing a specific class just for this since it's exactly the same properties as my typeOrm entity
If your DataminingShort entity isn't showing up in the docs, it might be because your nest-cli.json doesn't specify the correct dtoFileNameSuffix. I assume your DataminingShort is located in a DataminingShort.entity.ts but maybe not.
"compilerOptions": {
"plugins": [
{
"name": "#nestjs/swagger",
"options": {
"introspectComments": true,
"dtoFileNameSuffix": [".dto.ts", ".entity.ts"]
}
}
],
Another option might be to add #ApiExtraModels(DataminingShort) to your DataminingController controller class.
Related
I am working on specify ACL fields for fields inside objects. I have the validator to check for permission to edit a specific field. For example, the schema looks like this:
"basic_info": {
"properties": {
"cadi_id": {
...
},
"analysis_keywords": {
...
},
"abstract": {
"type": "string",
"title": "Abstract",
"acl": {
"users": ["test#test.org", "test1#test.org"]
}
},
"ana_notes": {
...
},
"conclusion": {
...
}
},
"title": "Basic Information",
"type": "object",
"id": "basic_info",
"required": ["cadi_id"]
}
I have the abstract field with acl. It works fine when the user(not in acl) is editing the abstract field and the validation error is thrown when the user is not in acl.
The problem comes when user(not in acl) is editing other field like conclusion and have the same ValidationError.
When editing any field in basic_info, for example conclusion field, the whole basic_info object is processed in the validator beacuse it's the parent field and now user should be able to edit the conclusion field because there is no acl set. but it gives the ValidationError because we also receive the abstract (which is unchanged) in the basic_info and it goes to validate method and since the user is not in acl it gives ValidationError .
Please let me know what I am missing here to let the user(not in acl) to edit the non acl field?
I tried to get the previous value from the db and check if the controlled field is edited by user or not, but it doesn't seems efficient for this use case and I want to know if there is any native way to do the field level validation. I could not find anything in the docs.
I have red the documentation of sequelize but could not get the idea/concept i wanted ,I don't want just one attribute to be shown.
We have the following syntax to get the attributes we need
Model.findAll({
attributes:['foo','bar]
})
In my case I have many attributes in single table , I just want to hide one attribute.Is there any way in sequelize that we define the attribute which we don't want to see and get all other by default..
For Example....
Model.findAll({
attributes:hide foo , show all other attributes
})
AnyOne Can help..
You can use below syntax.
Model.findAll({
attributes: {
exclude: ['foo'] // hide this
}
});
You can also exclude fields on model level by adding in their default scope like below.
const Model = sequelize.define('model',{
secretColumn: Sequelize.STRING,
//... and other columns
}, {
defaultScope: {
attributes: { exclude: ['secretColumn'] }
}
});
How to remove some fields of model from find* (Like password, token)?
I think overriding toJSON() function (Like here https://stackoverflow.com/a/27979695/6119618) is not a good way, because i sometimes need this field for password validation or token for checking etc..
Is there something like as .select('+token') as mongoose has?
And another question i think it's fit this topic.
How to remove generated by through fields from find* output?
When i call User.find() it responds { id: 0, name: 'somename', UserProjectsTie: { /* complex object of many-to-many relation table */ } }
To exclude an attribute from find*:
Model.findAll({
attributes: { exclude: ['baz'] }
});
To make this the default behavior, use a scope:
const Model = sequelize.define('Model', {
// Attributes
}, {
defaultScope: {
attributes: { exclude: ['baz'] }
}
});
Unless I'm mistaken the 'through' should only show up when using 'include'. To get rid of through in that case:
Model.findAll({
include: [{association: 'OtherModels', through: {attributes: []}}]
});
I have the following code in my 'user.js' model in ember-data:
export default DS.Model.extend({
organization: DS.belongsTo('organization'),
//other stuff
});
The CRUD for the website is working as expected, and in MongoDB I can see the following for the organization field of User:
"organization" : ObjectId("571974742ce868d575b79d6a"),
BUT, and I'm not sure if this is an error in my code or me not understanding how Ember-data works, I cannot access that ID from a model hook like so:
model(){
return this.store.findRecord("user", this.get("session.currentUser.id"))
.then(user => this.store.findRecord("location", {organization: user.organization}));
}
And if I go to the Ember inspector to observe the belongsTo attribute of the User object, I see:
organization: <(subclass of Ember.ObjectProxy):ember956>
But clicking through I see content: null
What am I doing wrong? Could it be a server-side error?
Edit including JSON response from server for the above findRecord("user") call:
{
"links":{
"self":"/users/5719749a2ce868d575b79d6b"
},
"included":[
{
"type":"organizations",
"id":"571974742ce868d575b79d6a",
"links":{
"self":"/organizations/571974742ce868d575b79d6a"
},
"attributes":{
"creation-date":"2016-04-22T00:46:44.779Z"
}
}
],
"jsonapi":{
"version":"1.0"
},
"data":{
"type":"users",
"id":"5719749a2ce868d575b79d6b",
"links":{
"self":"/users/5719749a2ce868d575b79d6b"
},
"attributes":{
"email":"danthwa#gmail.com",
"first-name":"Daniel",
"last-name":"Thompson",
"registration-date":"2016-04-22T00:47:22.534Z"
},
"relationships":{
"organization":{
"type":"organizations",
"id":"571974742ce868d575b79d6a"
}
}
}
}
Confirmed. As stated by Kingpin2k,
the relationships isn't being built up correctly, I think the type and id inside of organization need to be within a data object.
This applies to Ember sites expecting a JSON API spec payload, meaning they have been configured to use JSONAPISerializer for incoming payloads.
caveat: new to web programming. I have the following in a sails project:
// in models/User.js
// user has many videos
module.exports = {
attributes: {
videos: {
collection: 'video',
via: 'owner'
}
}
}
// in models/Video.js
// video has one user
module.exports = {
attributes: {
owner: {
model: 'user'
}
}
}
I'm using the REST blueprints with a /v1 prefix. I'm trying to either override GET /v1/user/:id/video, or make a custom route to GET /v1/user/:id/myGetVideo
So I've tried the following:
find and findOne methods in VideoController.js and UserController.js. These don't trigger for GET /v1/user/:id/video - I guess because the many-to-one association is treated differently
creating a custom route
// in routes.js
module.exports.routes = {
'get /user/:id/myGetVideo': 'UserController.myGetVideo'
}
This doesn't trigger anything because of the namespace, but it does trigger /user/:id/myGetVideo as expected. I don't want to add /v1 namespace here b/c that will proliferate and become an issue to change versions.
So, how do I either override the method I want, or put it in the namespace? Overriding the first method seems cleaner, but idk.
Thanks for any help!
Edit: Any comments on what is better practice for a REST API?
Got it with wildcards:
// in routes.js
module.exports.routes = { 'get /v*/user/:id/myGetVideo':'UserController.myGetVideo' }
not bullet-proof if the prefix scheme changes, but good enough