Example with Monogdb ReamlWeb (#14555)
Added an Example using MongoDB's Realm-Web SDK ![Screenshot 2020-06-25 at 5 25 49 PM](https://user-images.githubusercontent.com/11258286/85715292-ebafa680-b708-11ea-98bd-d8d64701f0af.png) Fixes #14417
This commit is contained in:
parent
a8d2c1ee95
commit
1b5ca78810
5 changed files with 191 additions and 0 deletions
1
examples/with-realm-web/.env
Normal file
1
examples/with-realm-web/.env
Normal file
|
@ -0,0 +1 @@
|
|||
NEXT_PUBLIC_REALM_APP_ID=realm-example-bspbt
|
56
examples/with-realm-web/README.md
Normal file
56
examples/with-realm-web/README.md
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Realm-Web SDK Example
|
||||
|
||||
This example uses [Realm-Web SDK](https://docs.mongodb.com/realm/web/) to query a realm graphql endpoint using [swr](https://swr.now.sh/).
|
||||
|
||||
This example relies on [MongoDB Realm](https://www.mongodb.com/realm) for its GraphQL backend.
|
||||
|
||||
## Deploy your own
|
||||
|
||||
Deploy the example using [Vercel](https://vercel.com):
|
||||
|
||||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-realm-web)
|
||||
|
||||
## How to use
|
||||
|
||||
### Using `create-next-app`
|
||||
|
||||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
|
||||
|
||||
```bash
|
||||
npx create-next-app --example with-realm-web with-realm-web-app
|
||||
# or
|
||||
yarn create next-app --example with-realm-web with-realm-web-app
|
||||
```
|
||||
|
||||
### Download manually
|
||||
|
||||
Download the example:
|
||||
|
||||
```bash
|
||||
curl https://codeload.github.com/vercel/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-realm-web
|
||||
cd with-realm-web
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
# or
|
||||
yarn
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
|
||||
|
||||
## Configuration
|
||||
|
||||
To set up your app:
|
||||
|
||||
1. Link a cluster that includes the [Atlas sample data sets](https://docs.atlas.mongodb.com/sample-data/)
|
||||
2. Configure permissions for the `sample_mflix.movies` collection. For this
|
||||
demo, you can assign ready only permissions for all authenticated users.
|
||||
3. Generate a collection schema for the `sample_mflix.movies` collection.
|
||||
Add a root-level "title" field to the schema with the value set to "movie".
|
||||
4. Enable anonymous authentication
|
||||
5. Once your app is set up, replace the value of NEXT_PUBLIC_REALM_APP_ID in `.env` file with your App ID
|
23
examples/with-realm-web/lib/RealmClient.js
Normal file
23
examples/with-realm-web/lib/RealmClient.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { Credentials, App } from 'realm-web'
|
||||
|
||||
const APP_ID = process.env.NEXT_PUBLIC_REALM_APP_ID
|
||||
export const REALM_GRAPHQL_ENDPOINT = `https://realm.mongodb.com/api/client/v2.0/app/${APP_ID}/graphql`
|
||||
|
||||
const app = new App({
|
||||
id: APP_ID,
|
||||
baseUrl: 'https://realm.mongodb.com',
|
||||
})
|
||||
|
||||
export const generateAuthHeader = async () => {
|
||||
if (!app.currentUser) {
|
||||
// If no user is logged in, log in an anonymous user
|
||||
await app.logIn(Credentials.anonymous())
|
||||
}
|
||||
// Get a valid access token for the current user
|
||||
const { accessToken } = app.currentUser
|
||||
|
||||
// Set the Authorization header, preserving any other headers
|
||||
return {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
}
|
||||
}
|
17
examples/with-realm-web/package.json
Normal file
17
examples/with-realm-web/package.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "with-realm-web",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "latest",
|
||||
"react": "^16.7.0",
|
||||
"react-dom": "^16.7.0",
|
||||
"realm-web": "0.4.0",
|
||||
"swr": "0.2.3"
|
||||
},
|
||||
"license": "ISC"
|
||||
}
|
94
examples/with-realm-web/pages/index.js
Normal file
94
examples/with-realm-web/pages/index.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
import useSWR from 'swr'
|
||||
import { generateAuthHeader, REALM_GRAPHQL_ENDPOINT } from '../lib/RealmClient'
|
||||
|
||||
const FIND_MOVIES = `
|
||||
query FindMovies{
|
||||
movies(query: { year: 2014, rated: "PG" } ) {
|
||||
title
|
||||
year
|
||||
runtime
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const fetcher = async (query) =>
|
||||
fetch(REALM_GRAPHQL_ENDPOINT, {
|
||||
method: 'POST',
|
||||
headers: await generateAuthHeader(),
|
||||
body: JSON.stringify({ query }),
|
||||
}).then((res) => res.json())
|
||||
|
||||
const IndexPage = () => {
|
||||
const { data } = useSWR(FIND_MOVIES, fetcher)
|
||||
|
||||
if (data && data.error) {
|
||||
console.error(data.error)
|
||||
return <p>An error occurred: ${data.error}</p>
|
||||
}
|
||||
const movies = data ? data.data.movies : null
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="App">
|
||||
<h1>"PG" Rated Movies - 2014</h1>
|
||||
|
||||
{data ? (
|
||||
!movies && <div className="status">No movies Found</div>
|
||||
) : (
|
||||
<div className="status"> Fetching data...</div>
|
||||
)}
|
||||
|
||||
{movies && (
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Title</th>
|
||||
<th>Runtime</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{movies.map((movie, index) => {
|
||||
return (
|
||||
<tr key={index}>
|
||||
<td>{index + 1}</td>
|
||||
<td>{movie.title}</td>
|
||||
<td>{movie.runtime}</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<style jsx>{`
|
||||
th,
|
||||
td {
|
||||
padding: 15px;
|
||||
text-align: left;
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
th {
|
||||
background-color: #69bef0;
|
||||
color: white;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
.status {
|
||||
text-colour: red;
|
||||
text-align: center;
|
||||
}
|
||||
`}</style>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default IndexPage
|
Loading…
Reference in a new issue