Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

How to publish a forward facing api in sveltekit

$
0
0

I know that perhaps a dedicated server would be better for this, however I'm not familiar with server only frameworks. But I'm very familiar with SvelteKit api routes. I decided to create a route named "/API" Where I have a handler class that will determine which method to run in the server based on the string passed as the func parameter in the post request. This does return the data properly when I'm using the svelte client. However, after publishing the file to Vercel It was not able to fetch the data. I will include the error message at the end since it's very long.Here is the "/API/+server.ts" file

import { json, type RequestEvent } from '@sveltejs/kit';  export async function POST({request}:RequestEvent){    const body = await request.json()    const handler = new API_service(body.func);    const params =body.params    let data;    if (Array.isArray(params)) {        data = await handler.function_handler(params);    } else {        // Handle the case where body.params is not an array        throw new Error("No parameters array")    }    return json( data );}class API_service{    private func:string;    private config = {        api_key:"&x_cg_demo_api_key=Your coingecko API Key", //<--- Change accordingly        base_url:"https://api.coingecko.com/api/v3",        currency:"?vs_currency=usd",        ids:"&ids=bitcoin",        days:"&days=30"      }    private coins_endpoint = {        markets:"/coins/markets",      }    private root_endpoint = {        ping:"/ping"      }    constructor(func:string){        this.func=func    }    public function_handler(params:any[]){        switch(this.func){            case "get_btc_ohlc":                return this.get_btc_ohlc(params[0])        }    }    private async get_btc_ohlc(id:string){        const response = await fetch(this.config.base_url+`/coins/${id}/ohlc`+this.config.currency+this.config.days)        return await response.json()    }}

I tested the endpoint with the following client side code and I got the expected response

<script>    import {onMount} from "svelte";    onMount(async ()=>{        try {            const response = await fetch('/API',{                method:"POST",                body:JSON.stringify({                    func:"get_btc_ohlc",                    params:["bitcoin"]                })            })            if(!response.ok) {                throw new Error(`HTTP error! status: ${response.status}`);            }            console.log(await response.json());            } catch (error) {            console.error('There was a problem with the fetch operation: ', error);            }    })</script>

After using copilot extensively to solve this problem as well as looking online, I was unable to find a solution after several hour. Here are the suggestions copilot gave me

  1. Create a vercel.json file
  2. Create a hook.server.ts file
  3. Create a meta tag in app.htmlHere they are acordingly

vercel.json

{"headers": [      {"source": "/(.*)","headers": [          {"key": "Content-Security-Policy","value": "default-src *; connect-src 'self' https://private-coingecko-api.vercel.app; script-src 'self''unsafe-inline'; style-src 'self''unsafe-inline'; img-src 'self' data:;"          }        ]      }    ]  }

hook.server.ts

import type { Handle, RequestEvent } from '@sveltejs/kit';export const handle: Handle = async ({ event, resolve } ) => {  const response = await resolve(event);  // Ensure response.headers exists  if (response.headers) {    response.headers.set('Content-Security-Policy',"default-src 'self'; script-src 'self''unsafe-inline'; style-src 'self''unsafe-inline'; img-src 'self' data:; connect-src 'self' https://private-coingecko-api.vercel.app;"    );  }  return response;};

The Meta tag in app.html

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self''unsafe-inline'; style-src 'self''unsafe-inline'; img-src 'self' data:; connect-src 'self' https://private-coingecko-api.vercel.app;">

The following snippet is of the actual fetch to my endpoint which returns the error following it (I Ran this from the console in the default edge blank page)

await fetch("https://private-coingecko-api.vercel.app/API",{    method:"POST",    body:JSON.stringify({        func:"get_btc_ohlc",        params:["bitcoin"],        apikey: "Your api key" //<-- I removed the middleware in the previous snippet but its still there in production    })}).catch(error => console.error('Error:', error));

Error caused by fetch from the console

Here is another error from postman

Postman error message from production api

Here are the Logs from my vercel server. As you can see, the data from coingecko works just fine, however it fails to complete because of the cross site POST request. I modified my hooks file accordingly to a tutorial and here is how it looks, and it's still not working on postman.Vercel http request logs

import type { Handle } from '@sveltejs/kit';export const handle: Handle = async ({ resolve, event }) => {  // Apply CORS header for API routes  if (event.url.pathname.startsWith('/API')) {    // Required for CORS to work    if(event.request.method === 'OPTIONS') {      return new Response(null, {        headers: {'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS','Access-Control-Allow-Origin': '*','Access-Control-Allow-Headers': '*',        }      });    }  }  const response = await resolve(event);  if (event.url.pathname.startsWith('/API')) {        response.headers.append('Access-Control-Allow-Origin', `*`);  }  return response;};

Edit:I'm currently reading this, it seems useful so far I still haven't figured it outhttps://www.programonaut.com/cross-site-post-form-submissions-are-forbidden-in-sveltekit/

Here is more detailed documentation about this topichttps://kit.svelte.dev/docs/adapter-node

this information also seems relevanthttps://snippets.khromov.se/configure-cors-in-sveltekit-to-access-your-api-routes-from-a-different-host/


Viewing all articles
Browse latest Browse all 1541

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>