Skip to content

Commit

Permalink
Use cloudflare worker to proxy api calls
Browse files Browse the repository at this point in the history
Signed-off-by: Jay Wang <jay@zijie.wang>
  • Loading branch information
xiaohk committed Jul 12, 2024
1 parent 40c9d81 commit 5960b44
Show file tree
Hide file tree
Showing 11 changed files with 543 additions and 5 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"typescript": "^5.4.5",
"vite": "^5.2.12",
"vite-plugin-dts": "^3.9.1",
"vite-plugin-web-components-hmr": "^0.1.3"
"vite-plugin-web-components-hmr": "^0.1.3",
"wrangler": "^3.64.0"
}
}
14 changes: 10 additions & 4 deletions src/api/semantic-scholar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ const authorCitationSearchMocks = [
authorCitationSearchMockJSON9 as SemanticAuthorDetail[]
];

const proxyFetch = (url: string, options?: RequestInit) => {
const proxyUrl = 'https://recrec-api.jay-8dc.workers.dev';
const newURL = `${proxyUrl}?proxyUrl=${encodeURIComponent(url)}`;
return fetch(newURL, options);
};

/**
* Searches for an author by name using the Semantic Scholar API.
* @param query - The name of the author to search for.
Expand All @@ -52,7 +58,7 @@ export const searchAuthorByName = async (
): Promise<SemanticAuthorSearchResponse> => {
const baseURL = 'https://api.semanticscholar.org/graph/v1/author/search';
const url = `${baseURL}?query=${encodeURIComponent(query)}`;
const result = await fetch(url);
const result = await proxyFetch(url);
if (!result.ok) {
throw Error(`Search request failed with status: ${result.statusText}`);
}
Expand Down Expand Up @@ -104,7 +110,7 @@ export const searchAuthorDetails = async (

// Fetch the author details
try {
const response = await fetch(url, options);
const response = await proxyFetch(url, options);
const data = (await response.json()) as SemanticAuthorDetail[];

// downloadJSON(data, null, 'author.json');
Expand Down Expand Up @@ -137,7 +143,7 @@ export const getAllPapersFromAuthor = async (authorID: string) => {
const url = `${baseURL}?${encodedParameters.toString()}`;

// Fetch the paper details
const response = await fetch(url);
const response = await proxyFetch(url);
if (!response.ok) {
throw Error(
`Fetch error when getting paper details, status: ${response.status}`
Expand Down Expand Up @@ -189,7 +195,7 @@ export const getPaperCitations = async (paperIDs: string[]) => {
const url = `${baseURL}?${encodedParameters.toString()}`;

// Fetch the author details
const response = await fetch(url, options);
const response = await proxyFetch(url, options);
if (!response.ok) {
throw Error(
`Fetch error when getting author details, status: ${response.status}`
Expand Down
12 changes: 12 additions & 0 deletions src/recrec-api/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# http://editorconfig.org
root = true

[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
indent_style = space
70 changes: 70 additions & 0 deletions src/recrec-api/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:wc/recommended',
'plugin:lit/recommended',
'prettier'
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
tsconfigRootDir: __dirname,
project: ['./tsconfig.json', './tsconfig.node.json'],
extraFileExtensions: ['.cjs']
},
env: {
es6: true,
browser: true
},
plugins: ['lit', '@typescript-eslint', 'prettier'],
ignorePatterns: ['node_modules'],
rules: {
indent: 'off',
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single', { avoidEscape: true }],
'prefer-const': ['error'],
semi: ['error', 'always'],
// 'max-len': [
// 'warn',
// {
// code: 80
// }
// ],
'no-constant-condition': ['error', { checkLoops: false }],
'prettier/prettier': 2,
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_'
}
],
'no-self-assign': 'off'
}
};
172 changes: 172 additions & 0 deletions src/recrec-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Logs

logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)

report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json

# Runtime data

pids
_.pid
_.seed
\*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover

lib-cov

# Coverage directory used by tools like istanbul

coverage
\*.lcov

# nyc test coverage

.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)

.grunt

# Bower dependency directory (https://bower.io/)

bower_components

# node-waf configuration

.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)

build/Release

# Dependency directories

node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)

web_modules/

# TypeScript cache

\*.tsbuildinfo

# Optional npm cache directory

.npm

# Optional eslint cache

.eslintcache

# Optional stylelint cache

.stylelintcache

# Microbundle cache

.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history

.node_repl_history

# Output of 'npm pack'

\*.tgz

# Yarn Integrity file

.yarn-integrity

# dotenv environment variable files

.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)

.cache
.parcel-cache

# Next.js build output

.next
out

# Nuxt.js build / generate output

.nuxt
dist

# Gatsby files

.cache/

# Comment in the public line in if your project uses Gatsby and not Next.js

# https://nextjs.org/blog/next-9-1#public-directory-support

# public

# vuepress build output

.vuepress/dist

# vuepress v2.x temp and cache directory

.temp
.cache

# Docusaurus cache and generated files

.docusaurus

# Serverless directories

.serverless/

# FuseBox cache

.fusebox/

# DynamoDB Local files

.dynamodb/

# TernJS port file

.tern-port

# Stores VSCode versions used for testing VSCode extensions

.vscode-test

# yarn v2

.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.\*

# wrangler project

.dev.vars
.wrangler/
6 changes: 6 additions & 0 deletions src/recrec-api/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 140,
"singleQuote": true,
"semi": true,
"useTabs": false
}
17 changes: 17 additions & 0 deletions src/recrec-api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "recrec-api",
"version": "0.0.0",
"private": true,
"scripts": {
"deploy": "wrangler deploy",
"dev": "wrangler dev",
"start": "wrangler dev",
"cf-typegen": "wrangler types"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240701.0",
"itty-router": "^3.0.12",
"typescript": "^5.5.2",
"wrangler": "^3.60.3"
}
}
40 changes: 40 additions & 0 deletions src/recrec-api/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Welcome to Cloudflare Workers! This is your first worker.
*
* - Run `npm run dev` in your terminal to start a development server
* - Open a browser tab at http://localhost:8787/ to see your worker in action
* - Run `npm run deploy` to publish your worker
*
* Bind resources to your worker in `wrangler.toml`. After adding bindings, a type definition for the
* `Env` object can be regenerated with `npm run cf-typegen`.
*
* Learn more at https://developers.cloudflare.com/workers/
*/

export interface Env {
SEMANTIC_API: string;
}

export default {
async fetch(request, env, ctx): Promise<Response> {

Check failure on line 19 in src/recrec-api/src/index.ts

View workflow job for this annotation

GitHub Actions / build (16, ubuntu-latest)

Parameter 'request' implicitly has an 'any' type.

Check failure on line 19 in src/recrec-api/src/index.ts

View workflow job for this annotation

GitHub Actions / build (16, ubuntu-latest)

Parameter 'env' implicitly has an 'any' type.

Check failure on line 19 in src/recrec-api/src/index.ts

View workflow job for this annotation

GitHub Actions / build (16, ubuntu-latest)

Parameter 'ctx' implicitly has an 'any' type.
const url = new URL(request.url);
const proxyUrl = url.searchParams.get('proxyUrl'); // get a query param value (?proxyUrl=...)

if (!proxyUrl) {
return new Response('Bad request: Missing `proxyUrl` query param', { status: 400 });
}

const newRequest = new Request(request, {
headers: {
...request.headers,
'x-api-key': `${env.SEMANTIC_API}`,
},
body: request.body,
});

// make subrequests with the global `fetch()` function
const res = await fetch(proxyUrl, newRequest);

return res;
},
} satisfies ExportedHandler<Env>;

Check failure on line 40 in src/recrec-api/src/index.ts

View workflow job for this annotation

GitHub Actions / build (16, ubuntu-latest)

Cannot find name 'ExportedHandler'.
Loading

0 comments on commit 5960b44

Please sign in to comment.