Databases
Uncover Pylon's seamless integration with databases, enabling you to effortlessly connect and interact with your data stores for enhanced functionality and data management.
Pylon seamlessly integrates with various databases, empowering developers to build robust web services with ease. While Pylon is agnostic to the choice of database, using Prisma is highly recommended due to its TypeScript type generation capabilities, which align well with Pylon's schema generation process.
Using Prisma
When integrating Prisma with Pylon, developers can leverage the automatic TypeScript type generation provided by Prisma to enhance type safety and streamline development.
Follow the setup instructions in the Prisma documentation (opens in a new tab) to set up Prisma in your project.
Here's an example of how to define a Pylon service using Prisma:
import {app} from '@getcronit/pylon'
import {PrismaClient} from '@prisma/client'
const prisma = new PrismaClient()
export const graphql = {
Query: {
// Example query using Prisma
getUser: async (id: number) => {
return await prisma.user.findUnique({
where: {id}
})
}
},
Mutation: {
// Example mutation using Prisma
createUser: async (data: any) => {
return await prisma.user.create({
data
})
}
}
}
export default app
Note
When using plain Prisma without additional extensions, relations are not
resolved automatically in the GraphQL schema. To resolve relations and create
paginatable connections, consider using @getcronit/prisma-extended-models
.
Using prisma-extended-models (recommended)
To simplify the process of defining GraphQL schemas with Prisma, developers can use the @getcronit/prisma-extended-models
package. This package extends Prisma models with additional fields and methods to facilitate the creation of paginatable connections and resolve relations automatically.
Installation
To install @getcronit/prisma-extended-models
, run the following command:
bun add @getcronit/prisma-extended-models
Usage
Now you can generate extended Prisma models and use them in your Pylon services.
bunx prisma-extended-models generate
This command generates extended Prisma models in the src/models
directory. You can import these models in your Pylon services to automatically resolve relations and create paginatable connections.
Models structure
The generated extended Prisma models include the following structure:
my-pylon-project/
βββ src/
β βββ repository/
β β βββ models/
β β β βββ Post.ts
β β β βββ Author.ts
β β β βββ User.ts
β β βββ .generated.ts
β β βββ client.ts
The Post
, Author
, and User
models are extended with additional fields and methods to resolve relations and create paginatable connections. The client.ts
file exports the Prisma client instance, and the .generated.ts
file contains the generated Prisma models and helper functions.
Note
All models can be extended with additional fields and methods. This allows developers to customize the models according to their requirements, for example, securing sensitive fields with access control.
Here's an example of how to use extended Prisma models in a Pylon service:
import {app} from '@getcronit/pylon'
import {Post} from '../repository/models'
export const graphql = {
Query: {
// Example query using extended Prisma models
getPost: async (id: number) => {
return await Post.get({
id
})
},
allPosts: async () => {
return await Post.paginate()
}
},
Mutation: {
// Example mutation using extended Prisma models
createPost: async (data: any) => {
return await Post.create({
data
})
}
}
}
export default app
Assuming the Post
model has a relation to the User
model, the extended Prisma model will automatically resolve the relation when fetching a post and create paginatable connections for the User
model.
Note
When using extended Prisma models, ensure that the generated models are
up-to-date with your Prisma schema. You can regenerate the models by running
the bunx prisma-extended-models generate
command.
Example in action
GraphQL query example
query {
allPosts {
edges {
node {
id
title
content
author {
id
name
}
}
}
}
}
The result will include paginated posts with their authors resolved automatically.
Deploment with Prisma
Make sure to update your Dockefile
to include the Prisma schema and migrations in the deployment process. Here is a modified Dockerfile
that includes Prisma setup:
# use the official Bun image
# see all versions at https://hub.docker.com/r/oven/bun/tags
FROM oven/bun:1 as base
LABEL description="A Pylon project with Prisma"
LABEL org.opencontainers.image.source="https://github.com/cronitio/my-pylon-project"
LABEL maintainer="[email protected]"
WORKDIR /usr/src/pylon
# install dependencies into temp directory
# this will cache them and speed up future builds
FROM base AS install
ARG NODE_VERSION=20
RUN apt update \
&& apt install -y curl
RUN curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o n \
&& bash n $NODE_VERSION \
&& rm n \
&& npm install -g n
RUN mkdir -p /temp/dev
COPY package.json bun.lockb /temp/dev/
COPY prisma /temp/dev/prisma
RUN cd /temp/dev && bun install --frozen-lockfile
RUN cd /temp/dev && bun prisma generate
# install with --production (exclude devDependencies)
RUN mkdir -p /temp/prod
COPY package.json bun.lockb /temp/prod/
COPY prisma /temp/prod/prisma
RUN cd /temp/prod && bun install --frozen-lockfile --production
RUN cd /temp/prod && bun prisma generate
# copy node_modules from temp directory
# then copy all (non-ignored) project files into the image
FROM install AS prerelease
COPY --from=install /temp/dev/node_modules node_modules
COPY . .
# [optional] tests & build
ENV NODE_ENV=production
# Create .pylon folder (mkdir)
RUN mkdir .pylon
# RUN bun test
RUN bun run pylon build
# copy production dependencies and asource code into final image
FROM base AS release
RUN apt-get update -y && apt-get install -y openssl
COPY --from=install /temp/prod/node_modules node_modules
COPY --from=prerelease /usr/src/pylon/.pylon .pylon
COPY --from=prerelease /usr/src/pylon/package.json .
COPY --from=prerelease /usr/src/pylon/prisma prisma
# run the app
USER bun
EXPOSE 3000/tcp
ENTRYPOINT [ "bun", "run", "./node_modules/.bin/pylon-server" ]
Using other databases
For databases other than Prisma, such as MongoDB, developers need to define type interfaces separately and handle database operations accordingly. Here's an example of integrating MongoDB with Pylon:
import {app} from '@getcronit/pylon'
import {MongoClient} from 'mongodb'
const uri = 'mongodb://localhost:27017'
const client = new MongoClient(uri)
// Define MongoDB collections
let usersCollection: any
;(async () => {
await client.connect()
const database = client.db('myDatabase')
usersCollection = database.collection('users')
})()
export const graphql = {
Query: {
// Example query using MongoDB
getUser: async (id: string) => {
return await usersCollection.findOne({_id: id})
}
},
Mutation: {
// Example mutation using MongoDB
createUser: async (user: any) => {
await usersCollection.insertOne(user)
return user
}
}
}
export default app
Warning
When using other databases, ensure proper type definitions for Pylon to
maintain type safety and schema generation. When using the any
type, Pylon
will expose all data of the document to the schema, which may lead to security
vulnerabilities.
Conclusion
Integrating databases with Pylon is straightforward and flexible, allowing developers to choose the database that best fits their project requirements. Whether using Prisma, MongoDB, or other databases, Pylon provides the necessary tools to build robust web services efficiently.