Setting custom response header with Azure Function in proxies.json - azure

I am trying to add a custom HTTP header to all of my responses of my Azure Functions - lets call it X-Custom. Then I add a proxies.json file like this to my functions project:
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"add-custom-header-to-response": {
"matchCondition": {
"route": "/{*restOfPath}"
},
"responseOverrides": {
"response.headers.X-Custom": "Custom value"
}
}
}
}
And this works as expected, I do get the X-Custom header, but my response content has gone missing. What am I missing in the proxies.json file?
Update
Thanks to Baskar I came to the solution (I was missing backendUri):
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"add-custom-header-to-response": {
"matchCondition": {
"route": "/api/1/{*restOfPath}"
},
"backendUri": "https://localhost/api/1/{restOfPath}",
"responseOverrides": {
"response.headers.X-Custom": "Custom value"
}
}
}
}
Also see:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-proxies#reference-localhost
https://learn.microsoft.com/en-us/azure/azure-functions/functions-proxies#route-template-parameters

Just tested my azure function with the route as "test" and I have overriden my response status code and status description and added custom header. Your proxies.json is missing a function backend url.
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"test": {
"matchCondition": {
"route": "test"
},
"backendUri": "https://testbasenewtest.azurewebsites.net/api/HttpTrigger1",
"responseOverrides": {
"response.statusCode": "200",
"response.statusReason": "Successful Response",
"response.headers.API_Login": "custom"
}
}
}
}

Related

How to parameterize the values in workflow.json and connections.json files of azure logic app standard project

I have created azure logic app single tenant project using visual studio code by following this documentation. And then created workflow based on my requirement, this contains the data factory pipeline and send grid actions.
The workflow contains the hardcoded values in the create a pipeline run data factory action.
"Create_a_pipeline_run": {
"inputs": {
"host": {
"connection": {
"referenceName": "azuredatafactory_5"
}
},
"method": "post",
"path": "/subscriptions/#{encodeURIComponent('xxxxxxx-xxxx-xxxx-xxxx-xxxxxx')}/resourcegroups/#{encodeURIComponent('xxxxx')}/providers/Microsoft.DataFactory/factories/#{encodeURIComponent('xxxxxx')}/pipelines/#{encodeURIComponent('xxxxxxx')}/CreateRun",
"queries": {
"x-ms-api-version": "2017-09-01-preview"
}
},
"runAfter": {},
"type": "ApiConnection"
},
And the connections.json file looks file below:
"managedApiConnections": {
"sendgrid": {
"api": {
"id": "/subscriptions/#appsetting('WORKFLOWS_SUBSCRIPTION_ID')/providers/Microsoft.Web/locations/centralus/managedApis/sendgrid"
},
"authentication": {
"type": "ManagedServiceIdentity"
}
},
"azuredatafactory_5": {
"api": {
"id": "/subscriptions/#appsetting('WORKFLOWS_SUBSCRIPTION_ID')/providers/Microsoft.Web/locations/centralus/managedApis/azuredatafactory"
},
"authentication": {
"type": "ManagedServiceIdentity"
}
}
}
The above managed API connections refers the existing API connections from azure. But I want to create the new managed API connections per environment (means parameterize the values in the connections.json file based on the environment).
Can anyone suggest me how to parameterize the values in workflow.json files per environment and parameterize the values in connections.json file per environment.
A logic app standard is just an app service of kind workflowApp.
You can heavily make use of appsettings here.
Logic app parameters.
In your workflow.json, you can use parameters like that:
"Create_a_pipeline_run": {
"inputs": {
"host": {
"connection": {
"referenceName": "azuredatafactory_5"
}
},
"method": "post",
"path": "/subscriptions/#{encodeURIComponent(parameters('subscription_id'))}/resourcegroups/...",
"queries": {
"x-ms-api-version": "2017-09-01-preview"
}
},
"runAfter": {},
"type": "ApiConnection"
}
Then in your parameters.json file, reference app settings like that:
{
"subscription_id": {
"type": "String",
"value": "#appsetting('WORKFLOWS_SUBSCRIPTION_ID')"
}
}
subscription_id must be defined as an app setting in the app service.
Logic app connections.
In the same way you can use app settings and parameters for connection information in your connections.json file:
{
"managedApiConnections": {
"sendgrid": {
"api": {
"id": "/subscriptions/#appsetting('WORKFLOWS_SUBSCRIPTION_ID')/providers/Microsoft.Web/locations/centralus/managedApis/sendgrid"
},
...
"authentication": "#parameters('azure_authentication')"
}
}
}
then in your parameters.json file:
{
"azure_authentication": {
"type": "object",
"value": {
"type": "ManagedServiceIdentity"
}
}
...
}
This way you can easily offload all environment specific parameters to app settings

How to use openapi3 json specification to validate if Express application has set up correct routes?

Summary
I use orval to generate frontend code in order to fetch data from the backend. The API specification is using the openapi 3 format.
I want to be able to automatically validate if my express backend is implementing the correct endpoints by comparing the specification with the actual implementation.
Example
Let's assume that this is the specification api.json:
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "My Service"
},
"servers": [
{
"url": "http://my.service.com/api"
}
],
"paths": {
"/my-endpoint": {
"get": {
"summary": "List all things",
"operationId": "listThings",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Thing"
}
}
}
},
"default": {
"description": "unexpected error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Thing": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"Error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
}
}
}
Orval generates frontend code to fetch defined endpoints via axios and the according Typescript interfaces for request and response data.
So far so good.
Problem
My express backend does not know about the openapi specification. I need to manually create the correct express endpoints and make sure that they return the correct HTTP codes, correct response types and correct error handling.
I learned there are code generators like swagger-routes-express, but my concern with those is that they hide the endpoint definition and that it could be difficult to implement extra business logic to those endpoints. I may be wrong here, but i still didn't get how that would work in this scenario.
Desired solution
I think there are two variants that would be a great outcome:
A code generator that parses the api.json above and generates correct endpoints with proper Typescript types. It needs to be able to accept custom code in those endpoints which shouldn't be overwritten the next time the specification changes and code is regenerated.
A linter that checks the code if the correct endpoints exist and have the correct request and response types. Maybe a set of eslint rules.
Is there anything out there i could use for this?

Azure Custom resource provider - custom error message to ARM template

If my custom resource provider wants to return a custom failure message to ARM, what should be my response body?
I have a custom resource provider backed by a JavaScript Azure function
I tried the following
body = {
error: {
code: "Failed",
message: "A custom error message'."
}
};
httpStatus = 200;
context.res = {
status: httpStatus,
headers: {
'Content-Type': 'application/json'
},
body: body
};
The ARM template deployment fails with error -
{
"error": {
"code": "ResourceDeploymentFailure",
"message": "The response for resource had empty or invalid content."
}
I also tried
body = {
properties: {
provisioningState: "Failed",
error: {
code: "Failed",
message: "A custom error message'."
}
}
};
httpStatus = 200;
context.res = {
status: httpStatus,
headers: {
'Content-Type': 'application/json'
},
body: body
};
The ARM template deployment fails with error
"The resource operation completed with terminal provisioning state 'Failed"
I want the ARM template deployment to fail with a custom error message I return form the Azure function - "A custom error message'."
Edited:
Here is my ARM template
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourcePrefix": {
"type": "string",
"defaultValue": "prfx-",
"maxLength": 6,
"metadata": {
"description": "The prefix of HLF resource."
}
},
"randomGuid": {
"defaultValue": "[newGuid()]",
"type": "string",
"metadata": {
"description": "New random GUID"
}
}
},
"variables": {
"funcName": "[concat(parameters('resourcePrefix'), substring(parameters('randomGuid'), 0, 5))]",
"myResourceProvider": "my-custom-provider",
"location": "[resourceGroup().location]"
},
"resources": [
{
"apiVersion": "2018-09-01-preview",
"type": "Microsoft.CustomProviders/resourceProviders",
"name": "[variables('myResourceProvider')]",
"location": "[variables('location')]",
"properties": {
"resourceTypes": [
{
"name": "deploy",
"routingType": "Proxy",
"endpoint": "<azure-func-url>"
}
]
}
},
{
"apiVersion": "2018-09-01-preview",
"type": "Microsoft.CustomProviders/resourceProviders/deploy",
"name": "[concat(variables('myResourceProvider'), '/', variables('funcName'))]",
"location": "[variables('location')]",
"dependsOn": [
"[concat('Microsoft.CustomProviders/resourceProviders/',variables('myResourceProvider'))]"
]
}
],
"outputs": {
}
}
Proxying the error message as is, is not currently supported for Custom Providers. The custom error message would be nested as details under a standard message.
However, it looks like there is a bug that is stopping the propagation of the error through the ARM template. This should be fixed soon!
#jjbfour is right. The custom message is nested under "Downstream" label in the propagated message. But that is fine for me. The following works
body = {
error: {
code: "Failed",
message: "A custom error message'."
}
};
httpStatus = 400;
context.res = {
status: httpStatus,
headers: {
'Content-Type': 'application/json'
},
body: body
};
The mistake I was making earlier was not setting the HTTP status correctly.

Azure Function Proxy Regex Match Condition Route

I need to create a match condition route that matches several directories that I would like to adjust the Cache-Control header for. At the moment I have this:
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Locales": {
"matchCondition": {
"route": "/locales/{*url}"
},
"backendUri": "https://backend.com/locales/{url}",
"responseOverrides": {
"response.headers.Cache-Control": "max-age=1209600"
}
},
"App": {
"matchCondition": {
"route": "/app/{*url}"
},
"backendUri": "https://backend.com/app/{url}",
"responseOverrides": {
"response.headers.Cache-Control": "max-age=1209600"
}
},
"Fonts": {
"matchCondition": {
"route": "/fonts/{*url}"
},
"backendUri": "https://backend.com/fonts/{url}",
"responseOverrides": {
"response.headers.Cache-Control": "max-age=1209600"
}
}
}
}
Since I am doing the same thing with all three of these proxies, it would be nice if I could combine them into one with a regex match condition or something similar.
Is it possible to write a regex expression to match all of these routes? The docs do not seem to cover anything like this.
Regex match on route is not currently supported.

Azure Function Proxy to root

Anyone know what I am missing here?
I want my proxy to route all requests to my azure function root URL, to my function.
So that this link https://myfunction.azurewebsites.net/
works the same as this link https://myfunction.azurewebsites.net/MYShinyNewFunction
Here is my proxy.json
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Root URI to Redirector Trigger Function": {
"matchCondition": {
"route": "/{*path}",
"methods": [
"GET"
]
},
"backendUri": "https://localhost/{*path}"
}
}
}
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Root URI to Redirector Trigger Function": {
"matchCondition": {
"route": "/{*path}",
"methods": [
"GET"
]
},
"backendUri": "https://myfunction.azurewebsites.net/ActualFunctionName"
}
}
}
Figured it out

Resources