How can I fix the error: "Cannot POST /users. StatusCode: 404" while making a POST request in Postman? - post

I'm following the article while working on the project.
When making a POST request in Postman:
http://localhost:3000/users
With Body request:
{
"name": "Jose Luis",
"lastName": "Campos Bautista"
}
I'm getting the issue as:
{
"statusCode": 404,
"message": "Cannot POST /users",
"error": "Not Found"
}
Am I missing something in the steps of the article? Does it the problem related specifically to API?
Inside the controller I have annotated as users:
#Controller('users')
Before executing a Postman request, I run the command:
npm run start:dev
Also I use the Postgres database with the next format of configuration:
DB_URL=postgres://user:password#localhost:5444/dataBaseName
ENTITY_PATH=dist/**/**/*.entity{.js, .ts}
Thanks in advance for any reasonable advice/ideas on how I can overcome this issue.

I have looked in your git repo. You should insert some route inside your controller like this
#Post('/create')
Your service is also lacking await before calling the save method in your service. It should be like
async create(user: UserDto): Promise<UserDto> {
return await this.userRepository.save(user);
}
and your controller should be like
#Post()
async create(#Body() user: UserDto): Promise<UserDto> {
return await this.userService.create(user);
}
You also don't have a connection initialization inside your app.module.ts so your API wouldn't be able to save data inside database.

Your UserModule is never registered with the application. The AppModule needs to have UserModule in its imports array. Just because the file exists and is written doesn't mean Nest knows what to do with it. You have to tell the application that the module should be used by having it in the imports path of some module that eventually makes its way back to the root module (usually AppModule)
Side Note: when you do that, you will get an error from TypeORM because you call TypeormModule.forFeature() without ever importing TypeormModule.forRoot(), so just a heads up that you need to add that

Related

NestJS microservices error with "No matching message handler"

I'm building an application with microservices communicating through RabbitMQ (request-response pattern). Everything works fine but still I have a problem with error "There is no matching message handler defined in the remote service." - When I send POST to my Client app, it should simply send the message with data through client (ClientProxy) and the Consumer app should response. This functionality actually works, but always only for the second time. I know it sounds strange but on my first POST request there is always the error from Client and my every second POST request works. However this problem is everywhere in my whole application, so the particular POST request is just for the example.
Here is the code:
Client:
#Post('devices')
async pushDevices(
#Body(new ParseArrayPipe({ items: DeviceDto }))
devices: DeviceDto[]
) {
this.logger.log('Devices received');
return this.client.send(NEW_DEVICES_RECEIVED, devices)
}
Consumer:
#MessagePattern(NEW_DEVICES_RECEIVED)
async pushDevices(#Payload() devices: any, #Ctx() context: RmqContext) {
console.log('RECEIVED DEVICES');
console.log(devices);
const channel = context.getChannelRef();
const originalMsg = context.getMessage();
channel.ack(originalMsg);
return 'ANSWER';
}
Client has the RMQ settings with queueOptions: {durable: true} and the consumer as well queueOptions: {durable: true} with noAck: false
Please do you have any ideas what may causes the problem? I have tried sending the data with JSON.stringify and changing the message structure to {data: devices} but the error is still there.
I had same error and finally solve it today.
In my project, there is an api-gateway as a hybrid application to receive requests and pass data to other systems, every second request gives an error like below.
error: There is no matching message handler defined in the remote service.
Then I tried to remove the api-gateway hybrid application scope in the code below, the error is gone, hope this helps you out with this.
// api-gateway main.ts
const app = await NestFactory.create(AppModule);
// run as a hybrid app —→ remove it
app.connectMicroservice({
transport: Transport.RMQ,
noACK: false,
options: {
urls: [`amqp://${rmqUser}:${rmqPassword}#127.0.0.1:5672`],
queue: 'main_queue',
queueOptions: {
durable: false,
},
},
});
// run hybrid app
await app.startAllMicroservices(); —→ remove it
await app.listen(3000);
I solved this issue by placing the #EventPattern decorator on to a #Controller decorator method
I had this error while NOT using RabbitMQ. I found very little help online around this error message outside of it being related to RabbitMQ.
For me it was an issue where I was importing a DTO from another microservice in my microservice's Controller. I had a new DTO in my microservice that has a similar name to one in another microservice. I accidentally selected the wrong one from the automated list.
Since there wasn't any real indicator that my build was bad, just this error, I wanted to share in case others made the same mistake I did.
I encountered this same issue today and could not find any solution online and stumbled upon your question. I solved it in a hacky way and am not sure how it will behave when the application scales.
I basically added one #EventPattern (#MessagePattern in your case) in the controller of the producer microservice itself. And I called the client.emit() function twice.
So essentially the first time it gets consumed by the function that is in the producer itself and the second emit actually goes to the actual consumer.
This way only one POST call is sufficient.
Producer Controller:
#EventPattern('video-uploaded')
async test() {
return 1;
}
Producer client :
async publishEvent(data: VideosDto) {
this.client.emit('video-uploaded', data);
this.client.emit('video-uploaded', data);
}
I've experienced the same error in my another project and after some research I've found out that problem is in the way of distributing messages in RabbitMQ - named round-robin. In my first project I've solved the issue by creating a second queue, in my second project I'm using the package #golevelup/nestjs-rabbitmq instead of default NestJS library, as it is much more configurable. I recommend reading this question

Serverless - Change the content before deploy

I'm using Serverless for working with our aws lambda / appsync.
For Error Handling, we are keep erro code with message in a json file. The Codes will be unique. Something like this:
//error-code.json
{
"1"": { code: 1, message: "Invalid User Input"},
"2"": { code: 2, message: "Invalid Input"},
//... so on
}
This wil lbe deploy as layer and all the lambda will use it. Issue is we cannot use it in the resolve template. There are some of the resolver will be only template file. These template files cannot access the json file nor can access the layer. How can I use the error-code.json here?
Solution 1:
Manually write the error code in templates and make sure there are alway unique. Something like this:
#set(#errorInfo = {
"erroCode": "1",
"errorMessage": "Invalid Input"
})
$util.error("Invalid Input", "errorType", $ctx.arguments,#errorInfo)
Rejected: Becasue we have to manually check everytime for the unique of error code. In case of lot of template file, we cannot rely on it.
Solution 2:
Create a table with error code (unique) and error message. Use this table to send error from template.
Rejected: Because we use multiple app sync instance and they all connect to dirferent database. So we have to make this table in all database, and thus unique across the app-sync is not maintained.
Solution 3:
Write the placeholder in vtl where we want to send the error. Before Deploy, replace the placeholder with the actual code using pre-hook script, but not in the actual vtl file but in the generated package that serverless deploy. Does Serverless even such thing?
if your errors are all static, there is one more option for consideration.
You create one more file that holds all errors defined in Velocity.
$util.qr( $ctx.stash.put("errors", {}) ) $util.qr(
$util.qr( $ctx.stash.errors.put("ONE", { "code": 1, "message": "Invalid User
Input"} )
...
$util.qr( $ctx.stash.errors.put("TWENTY", { "code": 20, "message": "20th error description"} )
For every velocity resolver that throws errors, you inject pre-defined errors at the beginning of its request mapping's file. Whenever you want to throw an error, it's done by retrieving a pre-defined error from $ctx.stash
$util.error ( $ctx.stash.errors.ONE.message, $ctx.stash.errors.ONE.code )
The error file is generated from error-code.json, or manually typed again for simplicity. $ctx.stash is used because stash is accessible from everywhere in a resolver, including pipeline ones.

Create team from group fails with exception

I created teams in Microsoft Teams (from groups as documented here) via the C# graph-api sdk without any problems - everything was working just fine.
But suddenly this is not working anymore. I will always get the following exception at the line return await graphServiceClient.Teams.Request().AddAsync(team);:
Message: Failed to execute Templates backend request
CreateTeamFromGroupWithTemplateRequest. Request Url:
https://teams.microsoft.com/fabric/emea/templates/api/groups/theGroupId/team,
Request Method: PUT,
And further:
Team Visibility can not be specified as it is inherited from the
group.
I know that the visibility property must not be set if creating the team from a group as it states in the Microsoft documentation:
The team that's created will always inherit from the group's display name, visibility, specialization, and members. Therefore, when making this call with the group#odata.bind property, the inclusion of team displayName, visibility, specialization, or members#odata.bind properties will return an error.
But the currently used code below shows that I am not setting any forbidden properties - and this code worked for the last few days, too:
private async Task<Team> CreateTeamFromGroup(string groupId)
{
var graphServiceClient = [...]
var groupResourceLink = $"https://graph.microsoft.com/v1.0/groups('{groupId}')";
var team = new Team
{
AdditionalData = new Dictionary<string, object>()
{
{ "template#odata.bind", "https://graph.microsoft.com/beta/teamsTemplates('standard')" },
{ "group#odata.bind", groupResourceLink }
},
Channels = new TeamChannelsCollectionPage
{
new Channel
{
DisplayName = "WhatEver"
}
}
};
return await graphServiceClient.Teams.Request().AddAsync(team);
}
Is anyone else experiencing this problem? Was there an API change? Was the teams backend changed? Anyone any ideas?
P.S.: I am using the latest NuGet-Package for Microsoft Graph - downgrading didn't help.
Update (with a not very satisfying work-around)
The error can be reproduced via the graph api explorer, too.
The POST command above issues a PUT command, that is described here. With this request, the team can be created.
The documentation and the graph api snippet for C# is out-dated, though. You have to add odatatype = null to the properties when using the sdk
Unfortunately it is not possible to add channels in the same step. If you specify the property 'channels' it will just be ignored.
Update (Detailed error message)
System.AggregateException: 'One or more errors occurred. (Code:
BadRequest Message: Failed to execute Templates backend request
CreateTeamFromGroupWithTemplateRequest. Request Url:
https://teams.microsoft.com/fabric/emea/templates/api/groups/theGroupId/team,
Request Method: PUT, Response Status Code: BadRequest,
ErrorMessage : {"errors":[{"message":"Team Visibility can not be
specified as it is inherited from the
group."}],"operationId":"639448e414ece64caee8f52839585bf7"} Inner
error: AdditionalData: date: 2020-11-24T10:21:22 request-id:
37a28cac-3ac5-4bd2-a061-daf44c442fac client-request-id:
37a28cac-3ac5-4bd2-a061-daf44c442fac ClientRequestId:
37a28cac-3ac5-4bd2-a061-daf44c442fac )'
Just tested this morning and I can say, that the "old way" by using the beta API to create a team with a template works again. Don't know, how many other ways exist to do these things, but here is our current request, that works now (again).
POST https://graph.microsoft.com/beta/teams
{
"displayName": "My Group Name",
"description": "Some description",
"template#odata.bind": "https://graph.microsoft.com/beta/teamsTemplates('educationClass')",
"owners#odata.bind": [
"https://graph.microsoft.com/beta/users('<someValidUserId>')"
]
}
I think this will be just an intermediate state and when the bugs are fixed, they will publish the new version again and this kind of creation will fail again, but if in this case the v1.0 documented way will work this wouldn't be a big problem. But being informed BEFORE there roll-out starts would be great.
This was a Microsoft issue/ bug and is currently being fixed as stated here.

Cant find information about acceptable response from my site to zapier app on test step (It's "Action" on my site )

I can't find information about acceptable response content or code status from my site to zapier app on test step.
I have my site on Laravel and Zapier app for this site. In my Zapier app I have an action: "Create New Project". I made my "create" according to the example. Everything works except the testing step. I tested with the following zap:
Trello -> "New card created" trigger. Test successful.
My app -> "Create new project". Test fails with We had trouble sending your test through. Could not handle special, non-standard characters. Please contact support.
Strangely, the project was created successfully. Therefore, I think the problem lies in the response from my site to zapier:
// creates/project.js
// My perform function:
perform: (z, bundle) => {
const promise = z.request({
url: `${process.env.BASE_URL}/api/folder`,
method: 'POST',
body: JSON.stringify({
title: bundle.inputData.title,
}),
headers: {
'content-type': 'application/json',
}
});
return promise.then((response) => JSON.parse(response.content));
}
//ZapierController.php
public function addFolder(Request $request)
{
// Made record to DB, and other, after this returned same data which in request
return response()->json(['title' => $request['title']]);
}
Expected result - successful test on "Test this step". Can anyone help me?
David here, from the Zapier Platform team.
I already answered your support ticket, but I figured I'd reply here in case anyone else has the same issue.
The root problem is made clear when you run zapier logs on the cli:
== Log
Unhandled error: CheckError: Invalid API Response:
- Got a non-object result, expected an object from create ("title")
What happened:
Executing creates.сFolder.operation.perform with bundle
Invalid API Response:
- Got a non-object result, expected an object from create ("title")
Your server can reply with any 2xx status code, but the output needs to be valid json. Something like {"title": "my title here"} would certainly work. Users find it more helpful to get info about the project they just created, so the name, id, etc would be even better.
As for why this surfaced as a character encoding issue, I have no clue. We plan on getting to the bottom of it though!

XSODATA service doesn't support merge operation?

I am using SAP HANA xsodata service to create an ODATA service on a HANA table, which is working fine.
Updating the model with update parameter on sap.ui.model.odata.ODataModel works fine
Code:
oModel.update(sUrl, oEntry, {
success : //do something ,
error : //do something
});
Now I want to use MERGE in place of PUT while Updating, following the documentation
My code:
oModel.update(sUrl, oEntry, {
merge: true,
success : //do something ,
error : //do something
});
It's throwing an error as only Get, Post, Put and Delete is supported.
So, my question is, whether XSODATA service doesn't support MERGE?
If it supports MERGE, what is wrong with my code?
Error - The following problem occurred: HTTP request failed405,Method Not Allowed,{ "error": { "code": "", "message": { "lang": "en-US", "value": "Invalid HTTP method. Only GET, POST, PUT, DEL methods are allowed."}}}
It very much looks like the XS server only supports the following HTTP methods: GET, HEAD, POST, OPTIONS, PUT, DELETE, TRACE, CONNECT. To see this, visit
https://<your.server:port>/sap/hana/xs/admin/#/package/<your.package.in.dot.notation>
Navigate to the package that contains your ODATA service .xsodata file, not drill into but click the name, chose tab "CORS" and go [Edit]. Down the page you see what methods can be allowed.
The docs, all docs, are a bit vague, but this is the list.
The default settings say GET, HEAD, POST, OPTIONS are allowed, which fits your error message. The settings in that tab are obeyed, as I had to learn the hard way when I tried a PUTonce.
So we can conclude that, funnily, the UI5 docs advertise a method which is not supported by the XS server.

Resources