controller with guard and metadata
#UseGuards(RightsGuard)
#Rights('users')
#Level('write')
#Get('/clearAuthSuccess')
async clearAuthSuccess(): Promise<DefaultMessageDto> {
return this.authService.clearAuthSuccess()
}
This is what I want to achieve:
Related
I am trying to send file from Client (Angular) to the NestJS same way like it is working now with Java-springboot API.
I am using POST method in NestJS but, unfortunatelly I am not able to got any data from the body :
here is the code :
#Post('/uploadExportFile')
uploadAttachment(#Req() req: Request, #Body() attachment: ArrayBuffer): any {
console.log(attachment);
return {};
}
content-type is set in header on Client side, I am not sure if I need to set content-types there ? Content type depends on file mimetype it should be (application/pdf/png/jpeg)..not multiform or what I need to do to achieve that attachment object will not return empty {} .
req.body is undefined
What I need to do with that file is to again change it back to Base64 (in angular it is in Base64) but Java API consumes only byte[] so I need to keep that like it is on FE.
any suggestions what is wrong in this "simple" code?
** EDIT **
====↓ EDIT ↓====
Solution: request.body is undefined is:
NestJS use as default body jsonBody, so in that case you have to override for specific routes that you want to use raw-body, and if raw-body is used insted of jsonBody, then the body from request is not undefined and it contain ArrayBuffer.
What you need to do is something like this;
Create rawBody middleware raw-body.middleware.ts
import { Injectable, NestMiddleware } from '#nestjs/common';
import { Request, Response } from 'express';
import * as bodyParser from 'body-parser';
#Injectable()
export class RawBodyMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => any) {
bodyParser.raw({type: '*/*'})(req, res, next);
}
}
app.module.ts
export class AppModule implements NestModule {
public configure(consumer: MiddlewareConsumer): void {
consumer
.apply(RawBodyMiddleware)
.forRoutes({
path: '/uploadExportFile',
method: RequestMethod.POST,
})
.apply(JsonBodyMiddleware)
.forRoutes('*');
}
}
and you need to disable bodyparser in main.ts
const app = await NestFactory.create(AppModule, { bodyParser: false })
in new version of NestJS is introduced new option raw-body but I have no possibility to test that https://docs.nestjs.com/faq/raw-body#raw-body
frist thing send the content-type application/x-www-form-urlencoded
and sure you have add UseInterceptors Like FileInterceptor
you can import FileInterceptor
if you need to get buffer try use file.buffer
import {FileInterceptor} from "#nestjs/platform-express";
#Post('upload')
#UseInterceptors(FileInterceptor('file'))
async upload(#Req() request: RequestWithUser, #UploadedFile() file) {
if (!file) {
throw new HttpException('File is required', HttpStatus.BAD_REQUEST);
}
// you have file
return await this.storageService.upload(file, request.user);
}
I have a script groovy, this script for live fetching of docker image,
I want to add the authentication function with the private repository, but I am not familiar with groovy, who can help me, thanks
import groovy.json.JsonSlurper
// Set the URL we want to read from, it is MySQL from official Library for this example, limited to 20 results only.
docker_image_tags_url = "https://registry.adx.abc/v2/mysql/tags/list"
try {
// Set requirements for the HTTP GET request, you can add Content-Type headers and so on...
def http_client = new URL(docker_image_tags_url).openConnection() as HttpURLConnection
http_client.setRequestMethod('GET')
// Run the HTTP request
http_client.connect()
// Prepare a variable where we save parsed JSON as a HashMap, it's good for our use case, as we just need the 'name' of each tag.
def dockerhub_response = [:]
// Check if we got HTTP 200, otherwise exit
if (http_client.responseCode == 200) {
dockerhub_response = new JsonSlurper().parseText(http_client.inputStream.getText('UTF-8'))
} else {
println("HTTP response error")
System.exit(0)
}
// Prepare a List to collect the tag names into
def image_tag_list = []
// Iterate the HashMap of all Tags and grab only their "names" into our List
dockerhub_response.results.each { tag_metadata ->
image_tag_list.add(tag_metadata.name)
}
// The returned value MUST be a Groovy type of List or a related type (inherited from List)
// It is necessary for the Active Choice plugin to display results in a combo-box
return image_tag_list.sort()
} catch (Exception e) {
// handle exceptions like timeout, connection errors, etc.
println(e)
}
The problem has been resolved, thank you everyone for your help
// Import the JsonSlurper class to parse Dockerhub API response
import groovy.json.JsonSlurper
// Set the URL we want to read from, it is MySQL from official Library for this example, limited to 20 results only.
docker_image_tags_url = "https://registry.adx.vn/v2/form-be/tags/list"
try {
// Set requirements for the HTTP GET request, you can add Content-Type headers and so on...
def http_client = new URL(docker_image_tags_url).openConnection() as HttpURLConnection
http_client.setRequestMethod('GET')
String userCredentials = "your_user:your_passwd";
String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userCredentials.getBytes()));
http_client.setRequestProperty ("Authorization", basicAuth);
// Run the HTTP request
http_client.connect()
// Prepare a variable where we save parsed JSON as a HashMap, it's good for our use case, as we just need the 'name' of each tag.
def dockerhub_response = [:]
// Check if we got HTTP 200, otherwise exit
if (http_client.responseCode == 200) {
dockerhub_response = new JsonSlurper().parseText(http_client.inputStream.getText('UTF-8'))
} else {
println("HTTP response error")
System.exit(0)
}
// Prepare a List to collect the tag names into
def image_tag_list = []
// Iterate the HashMap of all Tags and grab only their "names" into our List
dockerhub_response.tags.each { tag_metadata ->
image_tag_list.add(tag_metadata)
}
// The returned value MUST be a Groovy type of List or a related type (inherited from List)
// It is necessary for the Active Choice plugin to display results in a combo-box
return image_tag_list.sort()
} catch (Exception e) {
// handle exceptions like timeout, connection errors, etc.
println(e)
}
here is the result
i'm trying to generate swagger JSON files using https://github.com/pseudomuto/protoc-gen-doc, I can't find a way to exclude some of the APIs of the grpc service/fields inside the messages.
found the relevant styling in swagger, but can't seem to find a way to add it in the protobuf file http://watson-developer-cloud.github.io/api-guidelines/swagger-coding-style.html#excluding-operations-from-the-sdks
service MyService {
rpc ExternalApi (ExternalApiRequest) returns (ExternalApiResponse) {
option (google.api.http) = {
post: "/my/externalApi"
};
}
rpc InternalApi (InternalApiRequest) returns (InternalApiResponse) {
option (google.api.http) = {
post: "/my/internalApi"
};
}
message ExternalApiResponse {
string prefix = 1;
string id = 2; // field to exclude
}
// message to exclude
message Header { }
is there a way to exclude actions / fields from the protocol buffer files?
You can add
string id = 2 [(grpc.gateway.protoc_gen_swagger.options.openapiv2_field).read_only = true];
I'm trying to generate multiple swagger.json documents and using Customize the Action Selection Process to determine which action goes to which swagger document.
Is it possible to have different DocInclusionPredicate for different swagger document?
For example, I have
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API - V1", Version = "v1" });
c.SwaggerDoc("v2", new Info { Title = "My API - V2", Version = "v2" });
})
How do I specify one DocInclusionPredicate for v1 and another DocInclusionPredicate for v2 document?
c.DocInclusionPredicate((docName, apiDesc) =>
{
if (docName == "v1")
{ /* actions for v1 */ }
else if (docName == "v2")
{ /* actions for v2 */ }
});
and then return true if the predicate belongs to the specific version or false if it shall be filetered out in the correct if-statement
The project I've been working on has taken many shapes over the last few months, but its most recent incarnation was one which involved a RESTful Rails backend with React, Jade and Express on the frontend. This worked fine since React and Jade handled any data rendering on the frontend, and it allowed us to break out the requests from one monolithic request to about three much, much tinier ones.
The mandate is now to merge the view components into Rails, and this...is where I'm stuck.
As I said before, the world was different - The RESTful Rails routes were on one side of the fence, and the client was on another, meaning that AJAX requests were the only game in town. Here are some sample routes:
v1/property/:field
v1/property2/:field
v1/property3/:field
All of these routes work independently of any UI, so for the purpose of this question, we should treat them as a data source.
These are all requested on a single dashboard-like page, with each request pertaining to a specific part of it, all backed by a search bar which allows one to insert a specific calendar date. I've got this visually working now in a single view (mind the polygons).
My main concern is the request to each of the three other parts of the view. It is unclear to me how to have each of these independently make their requests to the appropriate RESTful route with the appropriate value provided by the search bar.
I've tried a hackish approach to this particular problem:
Within the search module's JS file, on its submission, create a new event called doingSearch.
Use this event to provide the information I received from the search module's <input> tag, falling back to its placeholder value if I don't have anything else.
In _property.js.erb, I listen for this event and emit two AJAX requests:
The first request is to the endpoint, v1/property/:field, and if it is successful, the second request is a POST, which goes to a route /board/:field/handle_post. The belief here is that I have more control over this route, and can dictate what's rendered here.
I then render _property.html.erb at the end of _property.js.erb, but I would rather like to pass the JSON data into _property.html.erb as if it were a Rails model for simplicity's sake. If at all possible, the logical solution would be to render the view after the POST request had been submitted, but that's another sticking point - I'm unclear on how to approach that.
How would I go about accomplishing this?
If you are dealing with data you will want to use the flux pattern. Here is an example from https://github.com/calitek/ReactPatterns React.14/ReFluxSuperAgent. The api.store handles the actions that initiate an ajax request. The util/api.js handles the ajax requests. The basic.store receives the data through actions from util/api.js and passes the data on to the control component with events. The control component could then pass the relevant data on to other components as props. Those components can trigger events that are listened to by the api.store.
import Reflux from 'reflux';
import Actions from './Actions';
import ApiFct from './../utils/api.js';
let ApiStoreObject = {
newData: {
"React version": "0.14",
"Project": "ReFluxSuperAgent",
"currentDateTime": new Date().toLocaleString()
},
listenables: Actions,
apiInit() { ApiFct.setData(this.newData); },
apiInitDone() { ApiFct.getData(); },
apiSetData(data) { ApiFct.setData(data); }
}
const ApiStore = Reflux.createStore(ApiStoreObject);
export default ApiStore;
import request from 'superagent';
import Actions from '../flux/Actions';
let uri = 'http://localhost:3500';
module.exports = {
getData() { request.get(uri + '/routes/getData').end((err, res) => { this.gotData(res.body); }); },
gotData(data) { Actions.gotData1(data); Actions.gotData2(data); Actions.gotData3(data); },
setData(data) { request.post('/routes/setData').send(data).end((err, res) => { Actions.apiInitDone(); }) },
};
import Reflux from 'reflux';
import Actions from './Actions';
import AddonStore from './Addon.Store';
import MixinStoreObject from './Mixin.Store';
function _GotData(data) { this.data1 = data; BasicStore.trigger('data1'); }
let BasicStoreObject = {
init() { this.listenTo(AddonStore, this.onAddonTrigger); },
data1: {},
listenables: Actions,
mixins: [MixinStoreObject],
onGotData1: _GotData,
onAddonTrigger() { BasicStore.trigger('data2'); },
getData1() { return this.data1; },
getData2() { return AddonStore.data2; },
getData3() { return this.data3; }
}
const BasicStore = Reflux.createStore(BasicStoreObject);
export default BasicStore;
import React from 'react';
import BasicStore from './../flux/Basic.Store';
let AppCtrlSty = {
height: '100%',
padding: '0 10px 0 0'
}
const getState = () => {
return {
Data1: BasicStore.getData1(),
Data2: BasicStore.getData2(),
Data3: BasicStore.getData3()
};
};
class AppCtrlRender extends React.Component {
render() {
let data1 = JSON.stringify(this.state.Data1, null, 2);
let data2 = JSON.stringify(this.state.Data2, null, 2);
let data3 = JSON.stringify(this.state.Data3, null, 2);
return (
<div id='AppCtrlSty' style={AppCtrlSty}>
React 1.4 ReFlux with SuperAgent<br/><br/>
Data1: {data1}<br/><br/>
Data2: {data2}<br/><br/>
Data3: {data3}<br/><br/>
</div>
);
}
}
export default class AppCtrl extends AppCtrlRender {
constructor() {
super();
this.state = getState();
}
componentDidMount() { this.unsubscribe = BasicStore.listen(this.storeDidChange.bind(this)); }
componentWillUnmount() { this.unsubscribe(); }
storeDidChange(id) {
switch (id) {
case 'data1': this.setState({Data1: BasicStore.getData1()}); break;
case 'data2': this.setState({Data2: BasicStore.getData2()}); break;
case 'data3': this.setState({Data3: BasicStore.getData3()}); break;
default: this.setState(getState());
}
}
}