Closed HyperPandaz closed 3 years ago
Week 3 Step 3 ⬤⬤⬤◯◯◯◯◯◯ | 🕐 Estimated completion: 10-20 minutes
This week, you will be going through steps to handle POST requests with no data.
codename
and uses it to name the image.
uploadFile()
functionbunnimage/index.js
to the bunnimage
branchTo test your work, use Postman to send a POST request without an image attached. You should see a response similar to the below:
{
"body" : "Sorry! No image attached."
}
💡 Yay! This means the error was successfully caught.
Now we'll want to handle cases where the POST request's body happens to be empty. In your original module.exports
function, before you parse the body, make sure it exists! Only then should you upload your file to blob storage.
:bulb: Hint: You'll need to code the
uploadFile
function another parameter since it now has to receive the body, extension, AND filename!Headers
Headers are yet another way to pass on information in HTTP requests. Here's how to access them:
var the_header_value = req.headers['insert_header_name'];
In this case, the header value will be used to name our picture.
Week 3 Step 4 ⬤⬤⬤⬤◯◯◯◯◯ | 🕐 Estimated completion: 10-20 minutes
This week, you will be going through steps to create a Timer Trigger Function delete all files in your Blob storage container every 5 minutes. This allows for greater security for your users.
bunnimage-timer/index.js
on the bunnimage
branch and comment an expression that tells the Timer Trigger to run everyday at 6:23 AM.:bulb: Tip: Cron expressions might help you with the last task.
To test your work, use Postman to send a POST request with an image to your previous HTTP trigger function that will save your file within your blob. Recall that a successful save of your file will cause you to see a response similar to the below:
{
"body" : "File Saved"
}
You should also double check that your file has been saved by navigating to your storage blobs.
Now run your timer trigger function and re-check your storage blobs - they should be gone. Your logs notifying you of the blobs' deletions should also be displayed in your trigger function's console.
💡 Yay! This means your timer trigger function worked.
First, we'll need to create a new Azure Function that runs on a schedule with the Timer Trigger template.
bunnimage-timer
and select Timer trigger
Schedule
as 0 */5 * * * *
to have the function be triggered every 5 minutes.@azure/storage-blob
packageTo delete all the blobs in the container, you can first list all the blobs, then loop through deleting each one as you go.
Week 3 Step 5 ⬤⬤⬤⬤⬤◯◯◯◯ | 🕐 Estimated completion: 10-20 minutes
This week, you will be going through steps to create an HTTP Trigger that takes parameter inputs and returns a download link for the given image.
username
from blob storage using node-fetch
downloadUri
.BUNNIMAGE_ENDPOINT2
bunnimage-download/index.js
on the bunnimage
branchTo test your work, use Postman to send a GET request with a "username" in the header. You should see a response similar to the below:
:bulb: The username value should be the name of an image you have already uploaded to the blob storage. Do it fast, or your timer trigger will delete it!
{
"body" : {
"downloadUri" : "https://<YOUR_BLOB_STORAGE_URL>.blob.core.windows.net/images/<USERNAME>.png",
"success": true
}
}
💡 Yay! This means you successfully fetched a download link to your image.
In our module.exports
function, we'll want to:
Use the node-fetch
package we installed earlier this week to determine if the requested image is available.
Use if-else statements to determine the success of the retrieval. Remember to test for both jpeg and png extentions!
Send back a JSON object containing the download link.
Go ahead and merge this branch to main
to move on. Great work finishing this section!
⚠️ If you receive a
Conflicts
error, simply pressResolve conflicts
and you should be good to merge!
Week 3 Step 2 ⬤⬤◯◯◯◯◯◯◯ | 🕐 Estimated completion: 10-20 minutes
Upload it!
This week, you will be going through steps to upload images to blob storage using Azure's SDK.
✅ Task:
test
+ the correct file extensionBUNNIMAGE_ENDPOINT
, add your blob url to your repository secrets with the nameblob_url
, and commit your updated function code tobunnimage/index.js
on thebunnimage
branch🚧 Test Your Work
To test your work, you'll be using Postman to send a POST request in Postman with an image in the body to your function url. You should see a response similar to the below:
:question: How do I attach an image to my POST request?
1. Get your `bunnimage` function url 2. Use Postman to make a POST request to your functional url ![image](https://user-images.githubusercontent.com/49426183/120075487-4e669c00-c056-11eb-8049-d2e00c766525.png) 3. You will need to send body data with your request: - The Body tab in Postman allows you to specify the data you need to send with a request - You can send various different types of body data to suit your API - Website forms often send data to APIs as multipart/form-data - You can replicate this in Postman using the form-data Body tab - Be sure to check File instead of Text, since we'll be posting an image instead of a JSON object ![image](https://user-images.githubusercontent.com/49426183/120075704-393e3d00-c057-11eb-8d99-7dfe8d5fd584.png):exclamation: Check your blob storage container to see if the image is stored there:
![https://user-images.githubusercontent.com/69332964/99189316-9c592980-272e-11eb-9870-dbc1f9352599.png](https://user-images.githubusercontent.com/69332964/99189316-9c592980-272e-11eb-9870-dbc1f9352599.png)Writing our First Azure Function to Upload an Image
:exclamation: How do I initialize packages in code?
1. Use this [tutorial](https://docs.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings) to add in your own connection string from your storage container - The storage container is the one you created in step 1 - Navigate to the container and find your connection string 2. Add the following lines of code to the top of your index.js file: ```js var multipart = require("parse-multipart") const connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING; const { BlobServiceClient } = require("@azure/storage-blob"); ``` - Take note of the `process.env` value being assigned to `connectionString`. `AZURE_STORAGE_CONNECTION_STRING` is the name of the environment variable.:question: How do I find my secret strings?
These are the same ones you added in your repository secrets in step 1. Here is a review: ![https://user-images.githubusercontent.com/69332964/99161822-ec4ed680-26c3-11eb-8977-f12beb496c24.png](https://user-images.githubusercontent.com/69332964/99161822-ec4ed680-26c3-11eb-8977-f12beb496c24.png) - *Note: You'll need to store these strings in [environment variables](https://docs.microsoft.com/en-us/azure/app-service/configure-common) as well, if you don't want to accidentally commit them. You can access these with `process.env['thesecretname']`*1. Reviewing
parse-multipart
to receive an imageIn your main
module.exports
function, you'll want to use theparse-multipart
library to parse the image from the POST request. Then you'll determine the fle extension, and then upload the file using anuploadFile()
function we'll write later on.:question: Can we review syntax for `parse-multipart`?
To parse a request's body, you can use the following lines of code: ```js var boundary = multipart.getBoundary(req.headers['content-type']); var body = req.body; var parsedBody = multipart.Parse(body, boundary); ```2. Uploading the image
Let's start out by writing the function we can call to upload an iamge.
⬇ Uploading the image blob to your container
Our
uploadFile
function will be an asynchronous function that uses theBlobServiceClient
to get a reference to the container, create a blob, and upload the data to that blob.:question: What should my parameters be?
The signature of your `uploadFile()` function should look something like: ```js async function uploadFile(parsedBody, ext) ```:question: How can I get a reference to the container?
```js const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString); const containerName = ":question: How can I create a blob?
```js const blobName = 'test.' + ext; // Create the container const blockBlobClient = containerClient.getBlockBlobClient(blobName); // Get a block blob client ``` Based on previous code we've written and logic, fill in the blanks!:question: How can I upload data to the blob?
```js const uploadBlobResponse = await blockBlobClient.upload(parsedBody[0].data, parsedBody[0].data.length); ```Heading back to the
module.exports
main function:exclamation: Name your image file as
test.png
ortest.jpg
(depending on the submitted file extension) in our code for testing purposes.:question: How can I determine file extension?
You can use a series of if-else statements like the ones below: ```js var filetype = parsedBody[0].type; if (filetype == "image/png") { ext = "png"; } else if (filetype == "image/jpeg") { ext = "jpeg"; } else if (filetype == "image/jpg") { ext = "jpg" } else { username = "invalidimage" ext = ""; } ```:question: How can I upload the file?
In this case, we'll just call the `uploadFile()` function that we wrote earlier. ```js var responseMessage = await uploadFile(parsedBody, ext); context.res = { body: responseMessage }; ```🚀 Add your Blob URL as a secret
You'll need to add your Blob URL to the github repository as a secret so we can test it! Name our secret to
blob_url
and set it equal to your blob url, which should look like "https://bunnimagestorage.blob.core.windows.net". To find your url, simply place your storage account name in this template: