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.
Related
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?
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"
}
}
}
}
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
I have an ElasticSearch mapping as follows:
{
"person": {
"properties": {
"accounts": {
"type": "nested",
"properties": {
"username": {
"type": "string"
}
"account_type": {
"type": "string"
}
}
}
}
}
}
I want to write a query that matches the username for at least one of the nested accounts, but only returns the inner hit for the account that matches a specific type.
For example, for a person with accounts
{"accounts": [{"username": "Foo", "type": "foo-type"},
{"username": "Bar", "type": "bar-type"}]}}
I want a query that when searching for username "fo*", and type "bar-type", will return the user with an inner hit containing the nested object {"username": "Bar", "type": "bar-type"}, because the user has at least one account that matches the username, but the "bar-type" account type is always the one returned.
My query so far, looks like:
{
"query": {
"filtered": {
"query": {
"nested": {
"inner_hits": {
"size": 1
}
"path": "accounts",
"query": {
"bool": {
"must": [
{
"query": {
"wildcard": {
"accounts.username": {
"value": "fo*"
}
}
}
]
}
}
}
}
}
}
}
}
but (for obvious reasons) this returns the inner hit that matches the query. I'm not sure how to amend the query to return a different nested object that matches on the type "bar-type" as specified.
I have a query looking like this:
((company_id:1) AND (candidate_tags:"designer"))
However this also matches users where candidate_tags is interaction designer. How do I exclude these?
Here's my full search body:
{
"query": {
"filtered": {
"query": {
"query_string": {
"query":
"((company_id:1) AND (candidate_tags:\"designer\"))"
}
}
}
}
"sort":{
"candidate_rating":{
"order":"desc"
},
"candidate_tags",
"_score"
}
}
Extra info
Realised now that an answer came in: candidate_tags is an array of strings, and say, a candidate has the tags interaction designer and talent, searching for talent should be a match but designer should not.
Make your candidate_tags field as not_analyzed or analyzed with keyword analyzer.
{
"mappings": {
"test": {
"properties": {
"candidate_tags": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
or add a raw field to your existent mapping like this:
{
"mappings": {
"test": {
"properties": {
"candidate_tags": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
For the first option use the same query as you use now.
For the second option use candidate_tags.raw, like this:
{
"query": {
"filtered": {
"query": {
"query_string": {
"query": "((company_id:1) AND (candidate_tags.raw:\"designer\"))"
}
}
}
}
...
Another way is to use script:
POST test/t/1
{
"q":"a b"
}
POST test/t/2
{
"q":"a c"
}
POST test/t/_search
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "return _source.q=='a b'"
}
}
}
}
}
By filtering.
By making field candidate_tags an exact-value field - aka not_analyzed field (Andrei Stefan's solution, answered above)
With #2 be careful that you don't later mix the field that is not_analyzed with those that are. More: https://www.elastic.co/guide/en/elasticsearch/guide/current/_exact_value_fields.html
With #1, your query would look something like that (written from memory, don't have ES on me so can't verify):
{
"query": {
"filtered": {
"query": {
"query_string": {
"query":
"((company_id:1) AND (candidate_tags:\"designer\"))"
}
},
"filter" : {
"term" : {
"candidate_tags" : "designer"
}
}
}
}
"sort":{
"candidate_rating":{
"order":"desc"
},
"candidate_tags",
"_score"
}
}