Home > Software engineering >  SvelteKit: How to call mongodb without using endpoints?
SvelteKit: How to call mongodb without using endpoints?

Time:01-04

I want to call my database, but I don't want it be able to get accessed by end users by them going to the API endpoint that I set up. I was wondering how I would be able to just call my database from a file in the lib folder and just returning the data there. When I try it I get the error global not defined:

lib/db.js:

import dotenv from "dotenv";
dotenv.config();
import { MongoClient } from "mongodb";

const uri = process.env["MONGODB_URI"];
const options = {
  useUnifiedTopology: true,
  useNewUrlParser: true,
};

let client;
let clientPromise;

if (!uri) {
  throw new Error("Please add your Mongo URI to .env.local");
}

if (process.env["NODE_ENV"] === "development") {
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri, options);
    global._mongoClientPromise = client.connect();
  }
  clientPromise = global._mongoClientPromise;
} else {
  client = new MongoClient(uri, options);
  clientPromise = client.connect();
}
export default clientPromise;

routes/items/index.js:

import clientPromise from "$lib/db";

export async function get() {
  const client = await clientPromise;
  const db = client.db();
  const data = await db.collection("items").find({}).toArray();
  const items = data.map(({ name }) => ({ name }));

  if (items) {
    return {
      body: {
        items,
      },
    };
  }
}

My attempt: lib/stores/items.js

import clientPromise from "$lib/db";
import { writable } from "svelte/store";
export const items= writable([]);

const fetchItems = async () => {
  const client = await clientPromise;
  const db = client.db();
  const data = await db.collection("items").find({}).toArray();
  const items = data.map(({ name }) => ({ name }));

  substances.set(items);
};

fetchItems();

Trying the above code in various places always yields a global not defined error in the client.

I found one question from someone with the same problem, but I couldn't figure out how to create a helper file.

CodePudding user response:

Protecting API is done on back-end side. Usually it either server (like NodeJS) or tools Nginx/Apache (proxy, etc.). You're basically looking for Content-Security-Policy topic, which is vaporous but not related to SvelteKit.

Btw, calling DB directly from the Front-end wouldn't be secure and is not possible.

CodePudding user response:

To get data from any database, you should create enpoint

For user authentication, you can create handle hook:

export async function handle({ request, resolve }) {
  let user = await authenticate(request) 

  request.locals.user = user
  request.locals.isAuthenticated = !!user

  if (request.path.startsWith('/api')) {
    if (!user) {
      return {
        status: 401,
        body: JSON.stringify({
          error: {
            message: 'Unauthorized'
          }
        })
      }
    }

  const response = await resolve(request)
  return response
}
  • Related