Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Azure Cosmos DB started code, containing a minimal app and README.md #49128

Merged
merged 6 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/with-azure-cosmos/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
COSMOSDB_CONNECTION_STRING=
COSMOSDB_DATABASE_NAME=
COSMOSDB_CONTAINER_NAME=
35 changes: 35 additions & 0 deletions examples/with-azure-cosmos/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
67 changes: 67 additions & 0 deletions examples/with-azure-cosmos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
## Example app using Azure Cosmos DB

[Azure Cosmos DB](https://azure.microsoft.com/en-in/products/cosmos-db) is a fully managed NoSQL and relational database for modern app development. Azure Cosmos DB offers single-digit millisecond response times, automatic and instant scalability, along with guarantee speed at any scale. Business continuity is assured with SLA-backed availability and enterprise-grade security.

## Deploy your own

Once you have access to the environment variables you'll need, deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?project-name=with-azure-cosmos&repository-name=with-azure-cosmos&repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fwith-azure-cosmos&integration-ids=oac_mPA9PZCLjkhQGhlA5zntNs0L)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:

```bash
npx create-next-app --example with-azure-cosmos with-azure-cosmos-app
```

```bash
yarn create next-app --example with-azure-cosmos with-azure-cosmos-app
```

```bash
pnpm create next-app --example with-azure-cosmos with-azure-cosmos-app
```

## Configuration

### Set up a Azure Cosmos DB database

Set up a CosmosDB database with [Try Azure Cosmos DB free](https://cosmos.azure.com/try/).

### Set up environment variables

Copy the `env.local.example` file in this directory to `.env.local` (which will be ignored by Git):

```bash
cp .env.local.example .env.local
```

Set each variable on `.env.local`:

- `COSMOSDB_CONNECTION_STRING` - You will need your Cosmos DB connection string. You can find these in the Azure Portal in keys section.
- `COSMOSDB_DATABASE_NAME` - Name of the database you plan on using. This should already exist in the Cosmos DB account.
- `COSMOSDB_CONTAINER_NAME` - Name of the container you plan on using. This should already exist in the previous database.

### Run Next.js in development mode

```bash
npm install
npm run dev

# or

yarn install
yarn dev
```

Your app should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).

You will either see a message stating "You are connected to CosmosDB" or "You are NOT connected to CosmosDB". Please make sure you have provided valid environment variables.

When you are successfully connected, you can refer to the [Azure Cosmos DB client library for JavaScript/TypeScript](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/cosmosdb/cosmos) for further instructions on how to query your database.

## Deploy on Vercel

You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
57 changes: 57 additions & 0 deletions examples/with-azure-cosmos/lib/cosmosdb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Container, CosmosClient, Database } from '@azure/cosmos'

export type Cosmos = {
connected: boolean
client?: CosmosClient
database?: Database
container?: Container
}

if (!process.env.COSMOSDB_CONNECTION_STRING) {
throw new Error(
'Invalid/Missing environment variable: "COSMOSDB_CONNECTION_STRING"'
)
}

if (!process.env.COSMOSDB_DATABASE_NAME) {
throw new Error(
'Invalid/Missing environment variable: "COSMOSDB_DATABASE_NAME"'
)
}

if (!process.env.COSMOSDB_CONTAINER_NAME) {
throw new Error(
'Invalid/Missing environment variable: "COSMOSDB_CONTAINER_NAME"'
)
}

const connectionString = process.env.COSMOSDB_CONNECTION_STRING
const databaseName = process.env.COSMOSDB_DATABASE_NAME
const containerName = process.env.COSMOSDB_CONTAINER_NAME

let client
let database
let container

const cosmos: Cosmos = {
connected: true,
client,
database,
container,
}

try {
client = new CosmosClient(connectionString)
database = client.database(databaseName)
container = database.container(containerName)

cosmos.connected = true
cosmos.client = client
cosmos.database = database
cosmos.container = container
} catch (err) {
cosmos.connected = false
console.log(err)
}

export default cosmos
19 changes: 19 additions & 0 deletions examples/with-azure-cosmos/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@azure/cosmos": "^3.17.3",
"next": "latest",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "18.7.5",
"@types/react": "16.9.17",
"typescript": "4.6.3"
}
}
188 changes: 188 additions & 0 deletions examples/with-azure-cosmos/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import Head from 'next/head'
import { GetServerSideProps } from 'next'
import cosmos from '../lib/cosmosdb'

export type Props = {
isConnected: boolean
database?: {
name?: string
isConnected: boolean
numOfContainers?: number
}
container?: {
isConnected: boolean
name?: string
}
}

const Home = (props: Props) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to update this to use the App Router but non-blocking.

return (
<div className="container">
<Head>
<title>Next.js + Azure Cosmos DB</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<h1 className="title">
Welcome to <a href="https://nextjs.org">Next.js with CosmosDB!</a>
</h1>
{props.isConnected ? (
<h2 className="subtitle">You are connected to CosmosDB</h2>
) : (
<h2 className="subtitle">
You are NOT connected to CosmosDB. Check the <code>README.md</code>{' '}
for instructions.
</h2>
)}

<p className="description">
Get started by editing <code>pages/index.js</code>
</p>

{props.isConnected ? (
<div className="main">
<div className="grid">
<div className="card">
<h3>Database </h3>
<p>Name: {props.database?.name}</p>
<div>{`Number of Containers : ${props.database?.numOfContainers}`}</div>
<div>{`Status : ${
props.database?.isConnected ? 'Connected' : 'Not Connected'
}`}</div>
</div>
<div className="card">
<h3>Container</h3>
<p>Name: {props.container?.name}</p>
<div>{`Status : ${
props.database?.isConnected ? 'Connected' : 'Not Connected'
}`}</div>
</div>
</div>
</div>
) : (
<div></div>
)}

<style jsx>{`
.container {
min-height: 100vh;
padding: 0 0.5rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.main {
padding: 3rem 0;
flex: 1;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
flex-direction: column;
max-width: 1000px;
margin-top: 1rem;
}

.card {
margin: 1rem;
flex-basis: 45%;
padding: 1.5rem;
text-align: left;
color: inherit;
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
}

.card:hover,
.card:focus,
.card:active {
color: #0070f3;
border-color: #0070f3;
}

.card h3 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}

.card p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}

.card h4 {
margin: 0;
font-size: 1.25rem;
line-height: 1;
}
`}</style>

<style jsx global>{`
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
sans-serif;
}

* {
box-sizing: border-box;
}
`}</style>
</div>
)
}

export default Home

export const getServerSideProps: GetServerSideProps<Props> = async () => {
const props: Props = {
isConnected: false,
}

if (cosmos.connected) {
props.isConnected = true
try {
const { resource: database } = await cosmos.database!.read()
const containerIterator = cosmos.database!.containers.query({
query: 'SELECT * from p',
})
const { resources: containers } = await containerIterator.fetchAll()
props.database = {
isConnected: true,
name: database?.id,
numOfContainers: containers.length,
}
} catch {
props.database = {
isConnected: false,
}
}
try {
const { resource: container } = await cosmos.container!.read()
props.container = {
isConnected: true,
name: container?.id,
}
} catch {
props.database = {
isConnected: false,
}
}
}
return {
props,
}
}
Binary file added examples/with-azure-cosmos/public/favicon.ico
Binary file not shown.
20 changes: 20 additions & 0 deletions examples/with-azure-cosmos/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}