MicrosoftDocs / mslearn-build-api-azure-functions

MSLearn exercise code
MIT License
24 stars 58 forks source link

4-exercise-create-function-project steps fail, blocking issue in the learning module #31

Open JvdH-NL opened 5 months ago

JvdH-NL commented 5 months ago

Source: https://learn.microsoft.com/en-us/training/modules/build-api-azure-functions/4-exercise-create-function-project

Two blocking issues while going through this training module:

Step 5: can't create new project, GetProducts.ts already there. Checked in source code online, file is indeed there.

Step 7: refering to existing file: src/index.ts It is however not present (after clone, also checked online).

How should I be able to continue this training module?

glaucia86 commented 5 months ago

Hi, @JvdH-NL!

Thank you very much for your feedback. There was probably a mix-up. Probably between the branchs: main vs solution. And, I recreated the project using the v4 programming model configuration (previously main) someone just copied the files, without having created a new project using the Azure Functions extension. If you don't do it this way, the project won't run correctly.

I opened a Pull Request: HERE It's already in the main branch and you can proceed with the training now!

Thank you in advance for your feedback.

Sincerely,

Glaucia Lemos

JvdH-NL commented 5 months ago

Hi, thanks for your very quick response! Source: https://learn.microsoft.com/en-us/training/modules/build-api-azure-functions/4-exercise-create-function-project Step 5:

After this I got this stack trace (I had wiped whole directory + redid all the steps): [2024-03-27T20:51:12.080Z] Worker was unable to load entry point "dist/src/index.js": A function with id "GetProducts" has already been registered. [2024-03-27T20:51:12.089Z] Worker failed to index functions [2024-03-27T20:51:12.090Z] Result: Failure Exception: Worker was unable to load entry point "dist/src/index.js": A function with id "GetProducts" has already been registered. Stack: Error: Worker was unable to load entry point "dist/src/index.js": A function with id "GetProducts" has already been registered. at t.registerFunction (C:\Users\Janva\AppData\Roaming\npm\node_modules\azure-functions-core-tools\bin\workers\node\dist\src\worker-bundle.js:2:28844) at generic (C:\Users\Janva\OneDrive\Projects\mslearn-build-api-azure-functions\api\node_modules\@azure\functions\dist\azure-functions.js:491:17) at Object.http (C:\Users\Janva\OneDrive\Projects\mslearn-build-api-azure-functions\api\node_modules\@azure\functions\dist\azure-functions.js:442:5) at Object. (C:\Users\Janva\OneDrive\Projects\mslearn-build-api-azure-functions\api\dist\src\index.js:26:17) at Module._compile (node:internal/modules/cjs/loader:1369:14) at Module._extensions..js (node:internal/modules/cjs/loader:1427:10) at Module.load (node:internal/modules/cjs/loader:1206:32) at Module._load (node:internal/modules/cjs/loader:1022:12) at Module.require (node:internal/modules/cjs/loader:1231:19) at Object.apply (C:\Users\Janva\AppData\Roaming\npm\node_modules\azure-functions-core-tools\bin\workers\node\dist\src\worker-bundle.js:2:49412).

glaucia86 commented 5 months ago

Try to make this.... make git clone (for you local machine) and try it out firstly this approach? If doesn't work, let's schedule a Pair. So I can understand what happened here. Do you have a Discord account?

cc: @JvdH-NL

glaucia86 commented 5 months ago

Follow these steps:

Create a local.settings.json inside theapi` folder

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
    "CONNECTION_STRING": "<PAST_YOUR_CONNECTION_STRING_HERE>"
  },
  "Host": {
    "CORS": "*"
  }
}
JvdH-NL commented 5 months ago

Thanks for support. Instructions in Msft learn pages is not fully in sync with behaviour of code. I got most of it working, have to move along though. Thanks again.

glaucia86 commented 5 months ago

Thanks for support. Instructions in Msft learn pages is not fully in sync with behaviour of code. I got most of it working, have to move along though. Thanks again.

Thanks for the feedback! We are changing it according to your feedback so that it is in line with the audience's expectations. Please feel free to contact me, either on Twitter or Linkedin, to help you with Pair Programming so that you can get on with the exercise. Here's where you can find me. It would be a pleasure to help you.

https://linktr.ee/glaucia_lemos86

skurscheid commented 4 months ago

Hi there! I am adding my errors to this issue as I am experiencing the same problems as described by @JvdH-NL. I just wanted to add some observations that might help @glaucia86 to resolve this issue...

When following the instructions to run the debugger in order to execute the Azure Functions locally I experience the same error messages as above:

 *  Executing task in folder api: npm install 

up to date, audited 184 packages in 2s

71 packages are looking for funding
  run `npm fund` for details

1 low severity vulnerability

To address all issues, run:
  npm audit fix

Run `npm audit` for details.
 *  Terminal will be reused by tasks, press any key to close it. 

 *  Executing task in folder api: npm run clean 

> api@1.0.0 clean
> rimraf dist

 *  Terminal will be reused by tasks, press any key to close it. 

 *  Executing task in folder api: npm run build 

> api@1.0.0 build
> tsc

 *  Terminal will be reused by tasks, press any key to close it. 

 *  Executing task in folder api: func host start 

Azure Functions Core Tools
Core Tools Version:       4.0.5611 Commit hash: N/A +591b8aec842e333a87ea9e23ba390bb5effe0655 (64-bit)
Function Runtime Version: 4.31.1.22191

[2024-05-03T07:24:02.474Z] Worker was unable to load entry point "dist/src/index.js": A function with id "GetProducts" has already been registered.
[2024-05-03T07:24:02.479Z] Worker failed to index functions
[2024-05-03T07:24:02.479Z] Result: Failure
[**2024-05-03T07:24:02.479Z] Exception: Worker was unable to load entry point "dist/src/index.js": A function with id "GetProducts" has already been registered.
[2024-05-03T07:24:02.479Z] Stack: Error: Worker was unable to load entry point "dist/src/index.js": A function with id "GetProducts" has already been registered.**
[2024-05-03T07:24:02.479Z]     at t.registerFunction (/usr/local/Cellar/azure-functions-core-tools@4/4.0.5611/workers/node/dist/src/worker-bundle.js:2:28844)
[2024-05-03T07:24:02.479Z]     at generic (/Users/skurscheid/Development/mslearn-build-api-azure-functions/api/node_modules/@azure/functions/dist/azure-functions.js:491:17)
[2024-05-03T07:24:02.479Z]     at Object.http (/Users/skurscheid/Development/mslearn-build-api-azure-functions/api/node_modules/@azure/functions/dist/azure-functions.js:442:5)
[2024-05-03T07:24:02.479Z]     at Object.<anonymous> (/Users/skurscheid/Development/mslearn-build-api-azure-functions/api/dist/src/index.js:26:17)
[2024-05-03T07:24:02.479Z]     at Module._compile (node:internal/modules/cjs/loader:1369:14)
[2024-05-03T07:24:02.479Z]     at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
[2024-05-03T07:24:02.479Z]     at Module.load (node:internal/modules/cjs/loader:1206:32)
[2024-05-03T07:24:02.479Z]     at Module._load (node:internal/modules/cjs/loader:1022:12)
[2024-05-03T07:24:02.480Z]     at Module.require (node:internal/modules/cjs/loader:1231:19)
[2024-05-03T07:24:02.480Z]     at Object.apply (/usr/local/Cellar/azure-functions-core-tools@4/4.0.5611/workers/node/dist/src/worker-bundle.js:2:49412).
[2024-05-03T07:24:03.354Z] Debugger listening on ws://127.0.0.1:9229/2e4e40ce-9739-46ef-ae92-731dd6e10dd1
[2024-05-03T07:24:03.355Z] For help, see: https://nodejs.org/en/docs/inspector
[2024-05-03T07:24:03.355Z] Could not parse the provided connection string
[2024-05-03T07:24:03.355Z] Error: Worker was unable to load entry point "dist/src/index.js": A function with id "GetProducts" has already been registered.
[2024-05-03T07:24:03.355Z]     at t.registerFunction (/usr/local/Cellar/azure-functions-core-tools@4/4.0.5611/workers/node/dist/src/worker-bundle.js:2:28844)
[2024-05-03T07:24:03.355Z]     at generic (/Users/skurscheid/Development/mslearn-build-api-azure-functions/api/node_modules/@azure/functions/dist/azure-functions.js:491:17)
[2024-05-03T07:24:03.355Z]     at Object.http (/Users/skurscheid/Development/mslearn-build-api-azure-functions/api/node_modules/@azure/functions/dist/azure-functions.js:442:5)
[2024-05-03T07:24:03.355Z]     at Object.<anonymous> (/Users/skurscheid/Development/mslearn-build-api-azure-functions/api/dist/src/index.js:26:17)
[2024-05-03T07:24:03.355Z]     at Module._compile (node:internal/modules/cjs/loader:1369:14)
[2024-05-03T07:24:03.355Z]     at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
[2024-05-03T07:24:03.355Z]     at Module.load (node:internal/modules/cjs/loader:1206:32)
[2024-05-03T07:24:03.355Z]     at Module._load (node:internal/modules/cjs/loader:1022:12)
[2024-05-03T07:24:03.355Z]     at Module.require (node:internal/modules/cjs/loader:1231:19)
[2024-05-03T07:24:03.356Z]     at Object.apply (/usr/local/Cellar/azure-functions-core-tools@4/4.0.5611/workers/node/dist/src/worker-bundle.js:2:49412)
[2024-05-03T07:24:03.468Z] No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
For detailed output, run func with --verbose flag.

Interestingly, when commenting out the "GetProducts" function that was added in step 4 of the exercise, the project does execute and following result is shown in the output of the debugger:

Core Tools Version:       4.0.5611 Commit hash: N/A +591b8aec842e333a87ea9e23ba390bb5effe0655 (64-bit)
Function Runtime Version: 4.31.1.22191

[2024-05-03T07:29:12.397Z] Debugger listening on ws://127.0.0.1:9229/8f37f8e5-ab20-435d-aba8-73675949a92b
[2024-05-03T07:29:12.397Z] For help, see: https://nodejs.org/en/docs/inspector
[2024-05-03T07:29:12.397Z] Could not parse the provided connection string
[2024-05-03T07:29:12.518Z] Worker process started and initialized.
[2024-05-03T07:29:12.640Z] Debugger attached.

Functions:

        CreateProduct: [POST] http://localhost:7071/api/products

        DeleteProduct: [DELETE] http://localhost:7071/api/products/{id}

        UpdateProduct: [PUT] http://localhost:7071/api/products/{id}

For detailed output, run func with --verbose flag.

I have the impression that the project was committed to the main branch of the repository in some kind of intermediate state which causes exceptions to occur when we try to continue with the exercise and add the "GetProducts" function. I would be very grateful for some feedback on how to solve this, as I would really like to understand how to implement the serverless APIs on Azure! :)

Edit: the code block without "GetProducts"

import { app } from "@azure/functions";
import { CreateProduct } from "./functions/CreateProduct";
import { DeleteProduct } from "./functions/DeleteProduct";
import { UpdateProduct } from "./functions/UpdateProduct";
//import { GetProducts } from "./functions/GetProducts";

app.http('CreateProduct', {
  methods: ['POST'],
  route: 'products',
  authLevel: 'anonymous',
  handler: CreateProduct
});

app.http('DeleteProduct', {
  methods: ['DELETE'],
  route: 'products/{id}',
  authLevel: 'anonymous',
  handler: DeleteProduct
});

app.http('UpdateProduct', {
  methods: ['PUT'],
  route: 'products/{id}',
  authLevel: 'anonymous',
  handler: UpdateProduct
});

/*
app.http('GetProducts', {
  methods: ['GET', 'POST'],
  authLevel: 'anonymous',
  handler: GetProducts
});
*/
lbulej3 commented 3 months ago

@skurscheid I ran into the exact same issue as you. Although a bit late, I'm gonna leave it here for others.

In the GetProducts.ts file, at the end there is this codeblock:

app.http('GetProducts', {
  methods: ['GET', 'POST'],
  authLevel: 'anonymous',
  handler: GetProducts
});

As you can see, it's the exact same as in the index.ts file. Just delete it from any of the files (although deleting it from GetProducts.ts is better because of consistency) at it will work as intended.

As a sidenote, in the excersice it shows using the specified route http://localhost:7071/api/GetProducts should already return a list of products, but I don't see how that could be possible since no implementation was done in the GetProducts function.

pjm4 commented 2 months ago

Would be good to know what to do when you get this message @glaucia86 :

image
pjm4 commented 2 months ago

One possible solution to fix the issues:

  1. In VS Code install the Azure Tools extension

  2. Clone the repo: git clone https://github.com/MicrosoftDocs/mslearn-build-api-azure-functions

  3. Open the workspace file products-manager.code-workspace

    If you get a message: "Detected an Azure Functions Project in folder "api" that may have been created outside of VS Code. Initialize for optimal use with VS Code?" answer Yes

  4. Run the Azure Functions: Create New Project... say NO to all replacements.

  5. Cut the GetProducts function out of the GetProducts.ts file, remove the POST method, as would conflict with the CreateProduct route, add a route products so it can be found, and place it in the api index.ts file instead for consistency:

app.http('GetProducts', {
  methods: ['GET'],
  authLevel: 'anonymous',
  route: 'products',
  handler: GetProducts
});
  1. Replace your GetProducts.ts with the solution file: https://github.com/MicrosoftDocs/mslearn-build-api-azure-functions/blob/solution/api/src/functions/GetProducts.ts

  2. Update .put(`${API}/products`, this.products[index]) to .put(`${API}/products/${this.products[index].id}`, this.products[index]) in the front-end index.ts file to allow the UpdateProduct PUT operation to work properly.

  3. Update "AzureWebJobsStorage": "skip" in local.settings.json to skip. This will stop the Connect to Storage Account from popping up when you start the debugger. It should look something like:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "skip",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
    "CONNECTION_STRING": "AccountEndpoint=https://tailwind-traders-12345.documents.azure.com:443/;AccountKey=random_string_of_chars==;"
  },
  "Host": {
    "CORS": "*"
  }
}
  1. From mslearn-build-api-azure-functions/frontend run npm start

  2. Run the debug command: "Debug: Select and Start Debugging"

  3. Visit: http://localhost:3000/ (port could be different so check console) from an Incognito Tab or you might get an "This site can’t provide a secure connection" error.

Phew!