diff --git a/README.md b/README.md index 19643c67de9d..a2e76dc63d25 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,32 @@ All AsyncAPI JSON Schema definition files are being served within the `/definiti This is possible thanks to the following: 1. A [Netlify Rewrite rule](https://docs.netlify.com/routing/redirects/rewrites-proxies/) located in the [netlify.toml](netlify.toml) file, which acts as proxy for all requests to the `/definitions/` path, serving the content from GH without having an HTTP redirect. -2. A [Netlify Edge Function](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/) that modifies the `Content-Type` header of the rewrite response to become `application/schema+json`. This lets tooling, such as [Hyperjump](https://json-schema.hyperjump.io), to fetch the schemas directly from their URL. +2. A [Netlify Edge Function](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/) that modifies the `Content-Type` header of the rewrite response to become `application/schema+json`. This lets tooling, such as [Hyperjump](https://json-schema.hyperjump.io), to fetch the schemas directly from their URL. + Please find a flowchart explaining the flow this edge function should accomplish: + ```mermaid + flowchart TD + Request(Request) -->schema-related{Is it requesting Schemas?} + schema-related -->|No| req_no_schemas[Let the original request go through] + req_no_schemas --> Response(Response) + schema-related -->|Yes| req_schemas[Fetch from GitHub] + req_schemas-->req_json{Was requesting a .json file?} + + req_json -->|No| Response(Response) + req_json -->|Yes| response_status{Response Status?} + + response_status -->|2xx| response_ok[OK] + response_status -->|304| response_cached[Not Modified] + response_status -->|Any other| response_ko + + response_ok --> set_headers[Set Response Content-Type header to application/schema+json] + set_headers --> send_metric_success[Send success metric] + response_cached -- cached:true --> send_metric_success + response_ko --> send_metric_error[Send error metric] + + send_metric_success -- file served from raw GH --> Response(Response) + send_metric_error --the errored response --> Response(Response) + ``` + ## Project structure diff --git a/netlify/edge-functions/serve-definitions.ts b/netlify/edge-functions/serve-definitions.ts index 3197f584478c..77c3141ee86a 100644 --- a/netlify/edge-functions/serve-definitions.ts +++ b/netlify/edge-functions/serve-definitions.ts @@ -7,28 +7,27 @@ const NR_METRICS_ENDPOINT = Deno.env.get("NR_METRICS_ENDPOINT") || "https://metr const URL_DEST_SCHEMAS = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/schemas"; const URL_DEST_DEFINITIONS = "https://raw.githubusercontent.com/asyncapi/spec-json-schemas/master/definitions"; -// Legitimate request: +// Schemas-related request: // Patterns: / OR // OR /// // Examples: /definitions OR /schema-store/2.5.0-without-$id.json OR /definitions/2.4.0/info.json -// Non-legitimate request: +// Schemas-unrelated request: // Patterns: ///* // Examples: /definitions/asyncapi.yaml OR /schema-store/2.4.0.JSON (uppercase) // -// Non-legitimate requests should not use our GitHub Token and affect the rate limit. Those shouldn't send metrics to NR either as they just add noise. -const legitimateRequestRegex = /^\/[\w\-]*\/?(?:([\w\-\.]*\/)?([\w\-$%\.]*\.json))?$/ +// Schemas-unrelated requests should not use our GitHub Token and affect the rate limit. Those shouldn't send metrics to NR either as they just add noise. +const SchemasRelatedRequestRegex = /^\/[\w\-]*\/?(?:([\w\-\.]*\/)?([\w\-$%\.]*\.json))?$/ export default async (request: Request, context: Context) => { let rewriteRequest = buildRewrite(request); let response: Response; if (rewriteRequest === null) { - rewriteRequest = request; - - response = await context.next(); - } else { - // Fetching the definition file - response = await fetch(rewriteRequest); + // This is a Schema-unrelated request. Let it go through and do not intercept it. + return await context.next(); } + // Fetching the definition file + response = await fetch(rewriteRequest); + const isRequestingAFile = request.url.endsWith('.json'); if (isRequestingAFile) { var metricName: string @@ -56,6 +55,7 @@ export default async (request: Request, context: Context) => { default: // Notifying NR of the error. metricName = "asyncapi.jsonschema.download.error"; + console.log("Error downloading JSON Schema file: " + response.status + " " + response.statusText); break; } } @@ -68,7 +68,7 @@ export default async (request: Request, context: Context) => { }; function buildRewrite(originalRequest: Request): (Request | null) { - const extractResult = legitimateRequestRegex.exec(new URL(originalRequest.url).pathname); + const extractResult = SchemasRelatedRequestRegex.exec(new URL(originalRequest.url).pathname); if (extractResult === null) { return null; }