


























Persistent data is essential to building modern web apps. We need it to save user information, bill customers, and more. Now you can use your favorite data storage technologies—Prisma, Mongoose, MySQL, and more—with npm and Deno.
This blog post will show you how to quickly get started with these npm modules with Deno:
Check out our Manual for more How To guides on getting started with data persistence npm modules.
Supply chain attacks are a known security issue on npm. Node installs and runs npm modules with access to everything by default, making it easier for a single malicious dependency to quietly compromise millions of end users.
Data storage is at even greater risk to supply chain attacks, as production data is sensitive, necessary to run a business, and can be accessed through environment variables.
Deno’s opt-in permission model ensures you know what your dependencies require access to. The permission system is granular enough for you to grant access to environment variables, the filesystem, and even FFI.
Prisma, a modern ORM with best-in-class developer experience, has been one of our top requested modules. Here’s a quick guide to getting started with Prisma and Deno.
This next section will show you how to quickly connect Prisma with Deno.
View source here or follow the video guide on our YouTube channel!
Let’s create the folder deno-prisma and navigate there.
mkdir deno-prisma & cd deno-prismaThen, let’s run prisma init with Deno:
deno run --allow-read --allow-env --allow-write npm:prisma@^4.5 initThis will generate
prisma/schema.prisma.
Let’s update it with the following:
generator client { provider = "prisma-client-js" previewFeatures = ["deno"] output = "../generated/client" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Dinosaur { id Int @id @default(autoincrement()) name String @unique description String }
Prisma should also have generated a .env file with DATABASE_URL. Let’s
assign DATABASE_URL to a PostreSQL connection string. In this example, we’ll
use a free PostgreSQL database from Supabase.
After you have updated your .env file, let’s create the database schema in
Prisma:
deno run npm:prisma@^4.5 db pushAfter that’s complete, we’ll need to generate a Prisma client for Data Proxy:
deno run npm:prisma@^4.5 generate --data-proxyIn order to use Prisma Data Platform, we’ll have to create and connect a GitHub repo. So let’s initialize the repository, create a new GitHub repo, add the remote origin, and push the repo.
After you’ve done that, sign up for a free Prisma Data Platform account.
Click New Project and select Import a Prisma Repository.
It’ll ask for a PostgreSQL connection string, which you have in your .env.
Paste it here. Then click Create Project.
You’ll receive a new connection string that begins with prisma://. Let’s grab
that and assign it to DATABASE_URL in your .env file, replacing your
PostgreSQL string from Supabase.
Prisma and PrismaClientNow, you’ll be able to import Prisma and PrismaClient into your Deno
project:
import { Prisma, PrismaClient } from "../generated/client/deno/edge.ts";
From here, you can seed your database, query your data, and more.
Check out our more in-depth How To guide with Prisma or learn how to deploy Prisma on Deno Deploy.
Mongoose is a popular, schema-based library that models data for MongoDB. Here is a quick guide to getting started.
View source here or follow our video guide on YouTube.
Let’s define a model in Mongoose. In a new file Dinosaur.ts, let’s add:
import { model, Schema } from "npm:mongoose@^6.7"; const dinosaurSchema = new Schema({ name: { type: String, unique: true }, description: String, createdAt: { type: Date, default: Date.now }, updatedAt: { type: Date, default: Date.now }, }); dinosaurSchema.path("name").required(true, "Dinosaur name cannot be blank."); dinosaurSchema.path("description").required( true, "Dinosaur description cannot be blank.", ); export default model("Dinosaur", dinosaurSchema);
DinosaurLet’s create a new file, main.ts, that will:
Dinosaurconsole.log the retrieved dinosaurimport mongoose from "npm:mongoose@^6.7"; import Dinosaur from "./model/Dinosaur.ts"; await mongoose.connect("mongodb://localhost:27017"); const deno = new Dinosaur({ name: "Deno", description: "The fastest dinosaur ever lived.", }); await deno.save(); const denoFromMongoDb = await Dinosaur.findOne({ name: "Deno" }); console.log( `Finding Deno in MongoDB -- \n ${denoFromMongoDb.name}: ${denoFromMongoDb.description}`, );
Your output should be:
Finding Deno in MongoDB --
Deno: The fastest dinosaur ever lived.Success!
Check out our more in-depth How To guide with Mongoose.
Apollo is a GraphQL server you can setup in minutes and use with your existing data source (or REST API). You can connect any GraphQL client to it to access the data and take advantage of typechecking and efficient fetching.
Let’s get a simple Apollo server up and running that will allow us to query some local data. We’re only going to need three files for this:
schema.ts to set up our data modelresolvers.ts to set up how we’re going to populate the data fields in our
schemamain.ts where the server is going to launchWe’ll start by creating them:
touch schema.ts resolvers.ts main.tsLet’s go through setting up each.
schema.tsOur schema.ts file describes our data. In this case, our data is a list of
dinosaurs. We want our users to be able to get the name and a short description
of each dino. In GraphQL language, this means that Dinosaur is our type,
and name and description are our fields. We can also define the data
type for each field. In this case, both are strings.
This is also where we describe the queries we allow for our data, using the special Query type in GraphQL. We have two queries:
dinosaurs which gets a list of all dinosaursdinosaur which takes in the name of a dinosaur as an argument and returns
information about that one type of dinosaur.We’re going to export all this within our typeDefs type definitions, variable:
export const typeDefs = ` type Dinosaur { name: String description: String } type Query { dinosaurs: [Dinosaur] dinosaur(name: String): Dinosaur } `;
If we wanted to write data, this is also where we would describe the Mutation to do so. Mutations are how you write data with GraphQL. Because we are using a static dataset here, we won’t be writing anything.
resolvers.tsA resolver is responsible for populating the data for each query. Here we have
our list of dinosaurs and all the resolver is going to do is either a) pass that
entire list to the client if the user requests the dinosaurs query, or pass
just one if the user requests the dinosaur query.
const dinosaurs = [ { name: "Aardonyx", description: "An early stage in the evolution of sauropods.", }, { name: "Abelisaurus", description: '"Abel\'s lizard" has been reconstructed from a single skull.', }, ]; export const resolvers = { Query: { dinosaurs: () => dinosaurs, dinosaur: (_: any, args: any) => { return dinosaurs.find((dinosaur) => dinosaur.name === args.name); }, }, };
With the later, we pass the arguments from the client into a function to match the name to a name in our dataset.
main.tsIn our main.ts we’re going to import the ApolloServer as well as graphql
and our typeDefs from the schema and our resolvers:
import { ApolloServer } from "npm:@apollo/server@^4.1"; import { startStandaloneServer } from "npm:@apollo/server@^4.1/standalone"; import { graphql } from "npm:graphql@^16.6"; import { typeDefs } from "./schema.ts"; import { resolvers } from "./resolvers.ts"; const server = new ApolloServer({ typeDefs, resolvers, }); const { url } = await startStandaloneServer(server, { listen: { port: 8000 }, }); console.log(`Server running on: ${url}`);
We pass our typeDefs and resolvers to ApolloServer to spool up a new
server. Finally, startStandaloneServer is a helper function to get the server
up and running quickly.
All that is left to do now is run the server:
deno run --allow-net --allow-read --allow-env main.tsYou should see Server running on: 127.0.0.1:8000 in your terminal. If you go
to that address you will see the Apollo sandbox where we can enter our
dinosaurs query:
query {
dinosaurs {
name
description
}
}This will return our dataset:
{
"data": {
"dinosaurs": [
{
"name": "Aardonyx",
"description": "An early stage in the evolution of sauropods."
},
{
"name": "Abelisaurus",
"description": "\"Abel's lizard\" has been reconstructed from a single skull."
}
]
}
}Or if we want just one dinosaur:
query {
dinosaur(name:"Aardonyx") {
name
description
}
}Which returns:
{
"data": {
"dinosaur": {
"name": "Aardonyx",
"description": "An early stage in the evolution of sauropods."
}
}
}Awesome!
Check out our more in-depth How To guide with Apollo.
This blog post showed how to get started with Prisma, Mongoose, and Apollo. We also have How To guides for other data persistence npm modules such as PlanetScale, Redis, and MySQL2, and will continue to add more.
Stuck? Get help on our Discord.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。