1626443520
Since we first launched MongoDB Atlas in June 2016, we’ve been working towards building a cloud database that not only delivers a first-class developer experience, but also simply just works: no setup, tuning, or maintenance required. Over the years, this has led to features like auto-scaling and click-to-create index suggestions, along with numerous optimizations to our automation engine.
We’re excited to announce that we’re one more step closer to realizing this vision with the introduction of serverless databases on MongoDB Atlas.
Serverless computing and NoOps have emerged as popular trends in modern application development. Cloud functions are commonly used to power business logic in applications, and many teams rely on completely automated IT operations.
The appeal of serverless technology is hard to deny: elastic scaling eliminates the need for upfront resource provisioning and ongoing maintenance, and consumption-based pricing means paying only for resources that are used. It abstracts and automates away many of the lower-level infrastructure decisions that developers don’t want to have to learn or manage so they can focus on building differentiated features.
When it comes to databases, compute and storage resources have traditionally been tightly coupled. Applying a serverless model to databases means decoupling them and changing the way engineering teams think about infrastructure. Rather than asking a developer to predict an application’s future workload patterns, break them down into individual resource requirements, and then map them to arbitrary units of database instance sizes, serverless databases offer a much simpler experience: define where your data lives, and get a database endpoint you can use.
This not only streamlines the database deployment process, it also eliminates the need to monitor and adjust capacity on an ongoing basis. Developers are free to focus on thinking about their data rather than their databases, and leave the lower-level infrastructure decisions to intelligent, behind-the-scenes automation.
#serverless
1678870808
CodeMirror component for React. Demo Preview: @uiwjs.github.io/react-codemirror
Features:
🚀 Quickly and easily configure the API.
🌱 Versions after @uiw/react-codemirror@v4
use codemirror 6. #88.
⚛️ Support the features of React Hook(requires React 16.8+).
📚 Use Typescript to write, better code hints.
🌐 The bundled version supports use directly in the browser #267.
🌎 There are better sample previews.
🎨 Support theme customization, provide theme editor.
Not dependent on uiw.
npm install @uiw/react-codemirror --save
import React from 'react';
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
function App() {
const onChange = React.useCallback((value, viewUpdate) => {
console.log('value:', value);
}, []);
return (
<CodeMirror
value="console.log('hello world!');"
height="200px"
extensions={[javascript({ jsx: true })]}
onChange={onChange}
/>
);
}
export default App;
import CodeMirror from '@uiw/react-codemirror';
import { StreamLanguage } from '@codemirror/language';
import { go } from '@codemirror/legacy-modes/mode/go';
const goLang = `package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}`;
export default function App() {
return <CodeMirror value={goLang} height="200px" extensions={[StreamLanguage.define(go)]} />;
}
@codemirror/legacy-modes/mode/cpp
=> @codemirror/lang-cpp
@codemirror/legacy-modes/mode/css
=> @codemirror/lang-css
@codemirror/legacy-modes/mode/html
=> @codemirror/lang-html
@codemirror/legacy-modes/mode/java
=> @codemirror/lang-java
@codemirror/legacy-modes/mode/javascript
=> @codemirror/lang-javascript
@codemirror/legacy-modes/mode/json
=> @codemirror/lang-json
@codemirror/legacy-modes/mode/lezer
=> @codemirror/lang-lezer
@codemirror/legacy-modes/mode/markdown
=> @codemirror/lang-markdown
@codemirror/legacy-modes/mode/php
=> @codemirror/lang-php
@codemirror/legacy-modes/mode/python
=> @codemirror/lang-python
@codemirror/legacy-modes/mode/rust
=> @codemirror/lang-rust
@codemirror/legacy-modes/mode/sql
=> @codemirror/lang-sql
@codemirror/legacy-modes/mode/xml
=> @codemirror/lang-xml
@codemirror/legacy-modes/mode/wast
=> @codemirror/lang-wast
Markdown language code is automatically highlighted.
import CodeMirror from '@uiw/react-codemirror';
import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
import { languages } from '@codemirror/language-data';
const code = `## Title
\`\`\`jsx
function Demo() {
return <div>demo</div>
}
\`\`\`
\`\`\`bash
# Not dependent on uiw.
npm install @codemirror/lang-markdown --save
npm install @codemirror/language-data --save
\`\`\`
[weisit ulr](https://uiwjs.github.io/react-codemirror/)
\`\`\`go
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
\`\`\`
`;
export default function App() {
return <CodeMirror value={code} extensions={[markdown({ base: markdownLanguage, codeLanguages: languages })]} />;
}
import { useEffect, useMemo, useRef } from 'react';
import { useCodeMirror } from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
const code = "console.log('hello world!');\n\n\n";
// Define the extensions outside the component for the best performance.
// If you need dynamic extensions, use React.useMemo to minimize reference changes
// which cause costly re-renders.
const extensions = [javascript()];
export default function App() {
const editor = useRef();
const { setContainer } = useCodeMirror({
container: editor.current,
extensions,
value: code,
});
useEffect(() => {
if (editor.current) {
setContainer(editor.current);
}
}, [editor.current]);
return <div ref={editor} />;
}
We have created a theme editor
where you can define your own theme. We have also defined some themes ourselves, which can be installed and used directly. Below is a usage example:
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { okaidia } from '@uiw/codemirror-theme-okaidia';
const extensions = [javascript({ jsx: true })];
export default function App() {
return (
<CodeMirror
value="console.log('hello world!');"
height="200px"
theme={okaidia}
extensions={[javascript({ jsx: true })]}
/>
);
}
import CodeMirror from '@uiw/react-codemirror';
import { createTheme } from '@uiw/codemirror-themes';
import { javascript } from '@codemirror/lang-javascript';
import { tags as t } from '@lezer/highlight';
const myTheme = createTheme({
theme: 'light',
settings: {
background: '#ffffff',
foreground: '#75baff',
caret: '#5d00ff',
selection: '#036dd626',
selectionMatch: '#036dd626',
lineHighlight: '#8a91991a',
gutterBackground: '#fff',
gutterForeground: '#8a919966',
},
styles: [
{ tag: t.comment, color: '#787b8099' },
{ tag: t.variableName, color: '#0080ff' },
{ tag: [t.string, t.special(t.brace)], color: '#5c6166' },
{ tag: t.number, color: '#5c6166' },
{ tag: t.bool, color: '#5c6166' },
{ tag: t.null, color: '#5c6166' },
{ tag: t.keyword, color: '#5c6166' },
{ tag: t.operator, color: '#5c6166' },
{ tag: t.className, color: '#5c6166' },
{ tag: t.definition(t.typeName), color: '#5c6166' },
{ tag: t.typeName, color: '#5c6166' },
{ tag: t.angleBracket, color: '#5c6166' },
{ tag: t.tagName, color: '#5c6166' },
{ tag: t.attributeName, color: '#5c6166' },
],
});
const extensions = [javascript({ jsx: true })];
export default function App() {
const onChange = React.useCallback((value, viewUpdate) => {
console.log('value:', value);
}, []);
return (
<CodeMirror
value="console.log('hello world!');"
height="200px"
theme={myTheme}
extensions={extensions}
onChange={onChange}
/>
);
}
initialState
to restore state from JSON-serialized representationCodeMirror allows to serialize editor state to JSON representation with toJSON function for persistency or other needs. This JSON representation can be later used to recreate ReactCodeMirror component with the same internal state.
For example, this is how undo history can be saved in the local storage, so that it remains after the page reloads
import CodeMirror from '@uiw/react-codemirror';
import { historyField } from '@codemirror/commands';
// When custom fields should be serialized, you can pass them in as an object mapping property names to fields.
// See [toJSON](https://codemirror.net/docs/ref/#state.EditorState.toJSON) documentation for more details
const stateFields = { history: historyField };
export function EditorWithInitialState() {
const serializedState = localStorage.getItem('myEditorState');
const value = localStorage.getItem('myValue') || '';
return (
<CodeMirror
value={value}
initialState={
serializedState
? {
json: JSON.parse(serializedState || ''),
fields: stateFields,
}
: undefined
}
onChange={(value, viewUpdate) => {
localStorage.setItem('myValue', value);
const state = viewUpdate.state.toJSON(stateFields);
localStorage.setItem('myEditorState', JSON.stringify(state));
}}
/>
);
}
value?: string
value of the auto created model in the editor.width?: string
width of editor. Defaults to auto
.height?: string
height of editor. Defaults to auto
.theme?
: 'light'
/ 'dark'
/ Extension
Defaults to 'light'
.import React from 'react';
import { EditorState, EditorStateConfig, Extension } from '@codemirror/state';
import { EditorView, ViewUpdate } from '@codemirror/view';
export * from '@codemirror/view';
export * from '@codemirror/basic-setup';
export * from '@codemirror/state';
export interface UseCodeMirror extends ReactCodeMirrorProps {
container?: HTMLDivElement | null;
}
export declare function useCodeMirror(props: UseCodeMirror): {
state: EditorState | undefined;
setState: import('react').Dispatch<import('react').SetStateAction<EditorState | undefined>>;
view: EditorView | undefined;
setView: import('react').Dispatch<import('react').SetStateAction<EditorView | undefined>>;
container: HTMLDivElement | null | undefined;
setContainer: import('react').Dispatch<import('react').SetStateAction<HTMLDivElement | null | undefined>>;
};
export interface ReactCodeMirrorProps
extends Omit<EditorStateConfig, 'doc' | 'extensions'>,
Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'placeholder'> {
/** value of the auto created model in the editor. */
value?: string;
height?: string;
minHeight?: string;
maxHeight?: string;
width?: string;
minWidth?: string;
maxWidth?: string;
/** focus on the editor. */
autoFocus?: boolean;
/** Enables a placeholder—a piece of example content to show when the editor is empty. */
placeholder?: string | HTMLElement;
/**
* `light` / `dark` / `Extension` Defaults to `light`.
* @default light
*/
theme?: 'light' | 'dark' | Extension;
/**
* Whether to optional basicSetup by default
* @default true
*/
basicSetup?: boolean | BasicSetupOptions;
/**
* This disables editing of the editor content by the user.
* @default true
*/
editable?: boolean;
/**
* This disables editing of the editor content by the user.
* @default false
*/
readOnly?: boolean;
/**
* Whether to optional basicSetup by default
* @default true
*/
indentWithTab?: boolean;
/** Fired whenever a change occurs to the document. */
onChange?(value: string, viewUpdate: ViewUpdate): void;
/** Some data on the statistics editor. */
onStatistics?(data: Statistics): void;
/** The first time the editor executes the event. */
onCreateEditor?(view: EditorView, state: EditorState): void;
/** Fired whenever any state change occurs within the editor, including non-document changes like lint results. */
onUpdate?(viewUpdate: ViewUpdate): void;
/**
* Extension values can be [provided](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions) when creating a state to attach various kinds of configuration and behavior information.
* They can either be built-in extension-providing objects,
* such as [state fields](https://codemirror.net/6/docs/ref/#state.StateField) or [facet providers](https://codemirror.net/6/docs/ref/#state.Facet.of),
* or objects with an extension in its `extension` property. Extensions can be nested in arrays arbitrarily deep—they will be flattened when processed.
*/
extensions?: Extension[];
/**
* If the view is going to be mounted in a shadow root or document other than the one held by the global variable document (the default), you should pass it here.
* Originally from the [config of EditorView](https://codemirror.net/6/docs/ref/#view.EditorView.constructor%5Econfig.root)
*/
root?: ShadowRoot | Document;
/**
* Create a state from its JSON representation serialized with [toJSON](https://codemirror.net/docs/ref/#state.EditorState.toJSON) function
*/
initialState?: {
json: any;
fields?: Record<'string', StateField<any>>;
};
}
export interface ReactCodeMirrorRef {
editor?: HTMLDivElement | null;
state?: EditorState;
view?: EditorView;
}
declare const ReactCodeMirror: React.ForwardRefExoticComponent<
ReactCodeMirrorProps & React.RefAttributes<ReactCodeMirrorRef>
>;
export default ReactCodeMirror;
export interface BasicSetupOptions {
lineNumbers?: boolean;
highlightActiveLineGutter?: boolean;
highlightSpecialChars?: boolean;
history?: boolean;
foldGutter?: boolean;
drawSelection?: boolean;
dropCursor?: boolean;
allowMultipleSelections?: boolean;
indentOnInput?: boolean;
syntaxHighlighting?: boolean;
bracketMatching?: boolean;
closeBrackets?: boolean;
autocompletion?: boolean;
rectangularSelection?: boolean;
crosshairCursor?: boolean;
highlightActiveLine?: boolean;
highlightSelectionMatches?: boolean;
closeBracketsKeymap?: boolean;
defaultKeymap?: boolean;
searchKeymap?: boolean;
historyKeymap?: boolean;
foldKeymap?: boolean;
completionKeymap?: boolean;
lintKeymap?: boolean;
}
import { EditorSelection, SelectionRange } from '@codemirror/state';
import { ViewUpdate } from '@codemirror/view';
export interface Statistics {
/** Get the number of lines in the editor. */
lineCount: number;
/** total length of the document */
length: number;
/** Get the proper [line-break](https://codemirror.net/docs/ref/#state.EditorState^lineSeparator) string for this state. */
lineBreak: string;
/** Returns true when the editor is [configured](https://codemirror.net/6/docs/ref/#state.EditorState^readOnly) to be read-only. */
readOnly: boolean;
/** The size (in columns) of a tab in the document, determined by the [`tabSize`](https://codemirror.net/6/docs/ref/#state.EditorState^tabSize) facet. */
tabSize: number;
/** Cursor Position */
selection: EditorSelection;
/** Make sure the selection only has one range. */
selectionAsSingle: SelectionRange;
/** Retrieves a list of all current selections. */
ranges: readonly SelectionRange[];
/** Get the currently selected code. */
selectionCode: string;
/**
* The length of the given array should be the same as the number of active selections.
* Replaces the content of the selections with the strings in the array.
*/
selections: string[];
/** Return true if any text is selected. */
selectedText: boolean;
}
export declare const getStatistics: (view: ViewUpdate) => Statistics;
All Packages
Name | NPM Version | Website |
---|---|---|
@uiw/react-codemirror | #preview | |
@uiw/codemirror-extensions-basic-setup | #preview | |
@uiw/codemirror-extensions-color | #preview | |
@uiw/codemirror-extensions-classname | #preview | |
@uiw/codemirror-extensions-events | #preview | |
@uiw/codemirror-extensions-hyper-link | #preview | |
@uiw/codemirror-extensions-langs | #preview | |
@uiw/codemirror-extensions-line-numbers-relative | #preview | |
@uiw/codemirror-extensions-mentions | #preview | |
@uiw/codemirror-extensions-zebra-stripes | #preview | |
@uiw/codemirror-themes | #preview |
Name | NPM Version | Website |
---|---|---|
@uiw/codemirror-themes-all | #preview | |
@uiw/codemirror-theme-abcdef | #preview | |
@uiw/codemirror-theme-androidstudio | #preview | |
@uiw/codemirror-theme-atomone | #preview | |
@uiw/codemirror-theme-aura | #preview | |
@uiw/codemirror-theme-bbedit | #preview | |
@uiw/codemirror-theme-bespin | #preview | |
@uiw/codemirror-theme-duotone | #preview | |
@uiw/codemirror-theme-dracula | #preview | |
@uiw/codemirror-theme-darcula | #preview | |
@uiw/codemirror-theme-eclipse | #preview | |
@uiw/codemirror-theme-github | #preview | |
@uiw/codemirror-theme-gruvbox-dark | #preview | |
@uiw/codemirror-theme-material | #preview | |
@uiw/codemirror-theme-noctis-lilac | #preview | |
@uiw/codemirror-theme-nord | #preview | |
@uiw/codemirror-theme-okaidia | #preview | |
@uiw/codemirror-theme-solarized | #preview | |
@uiw/codemirror-theme-sublime | #preview | |
@uiw/codemirror-theme-tokyo-night | #preview | |
@uiw/codemirror-theme-tokyo-night-storm | #preview | |
@uiw/codemirror-theme-tokyo-night-day | #preview | |
@uiw/codemirror-theme-vscode | #preview | |
@uiw/codemirror-theme-xcode | #preview |
Author: uiwjs
Source Code: https://github.com/uiwjs/react-codemirror
License: MIT license
1608388622
#mongodb tutorial #mongodb tutorial for beginners #mongodb database #mongodb with c# #mongodb with asp.net core #mongodb
1626443520
Since we first launched MongoDB Atlas in June 2016, we’ve been working towards building a cloud database that not only delivers a first-class developer experience, but also simply just works: no setup, tuning, or maintenance required. Over the years, this has led to features like auto-scaling and click-to-create index suggestions, along with numerous optimizations to our automation engine.
We’re excited to announce that we’re one more step closer to realizing this vision with the introduction of serverless databases on MongoDB Atlas.
Serverless computing and NoOps have emerged as popular trends in modern application development. Cloud functions are commonly used to power business logic in applications, and many teams rely on completely automated IT operations.
The appeal of serverless technology is hard to deny: elastic scaling eliminates the need for upfront resource provisioning and ongoing maintenance, and consumption-based pricing means paying only for resources that are used. It abstracts and automates away many of the lower-level infrastructure decisions that developers don’t want to have to learn or manage so they can focus on building differentiated features.
When it comes to databases, compute and storage resources have traditionally been tightly coupled. Applying a serverless model to databases means decoupling them and changing the way engineering teams think about infrastructure. Rather than asking a developer to predict an application’s future workload patterns, break them down into individual resource requirements, and then map them to arbitrary units of database instance sizes, serverless databases offer a much simpler experience: define where your data lives, and get a database endpoint you can use.
This not only streamlines the database deployment process, it also eliminates the need to monitor and adjust capacity on an ongoing basis. Developers are free to focus on thinking about their data rather than their databases, and leave the lower-level infrastructure decisions to intelligent, behind-the-scenes automation.
#serverless
1608388501
#MongoDB
#Aspdotnetexplorer
#mongodb #mongodb database #mongodb with c# #mongodb with asp.net core #mongodb tutorial for beginners #mongodb tutorial
1669718160
If you’re a developer, worrying about your database is not necessarily something you want to do. You likely don’t want to spend your time provisioning or sizing clusters as the demand of your application changes. You probably also don’t want to worry about breaking the bank if you’ve scaled something incorrectly.
With MongoDB Atlas, you have a few deployment options to choose from when it comes to your database. While you could choose a pre-provisioned shared or dedicated cluster, you’re still stuck having to size and estimate the database resources you will need and subsequently managing your cluster capacity to best fit demand. While a pre-provisioned cluster isn’t necessarily a bad thing, it might not make sense if your development becomes idle or you’re expecting frequent periods of growth or decline. Instead, you can opt for a serverless instance to help remove the capacity management burden and free up time to dedicate to writing code. Serverless instances provide an on-demand database endpoint for your application that will automatically scale up and down to zero with application demand and only charge you based on your usage.
In this short and sweet tutorial, we’ll see how easy it is to get started with a MongoDB Atlas serverless instance and how to begin to develop an application against it.
We’re going to start by deploying a new MongoDB Atlas serverless instance. There are numerous ways to accomplish deploying MongoDB, but for this example, we’ll stick to the web dashboard and some point and click.
From the MongoDB Atlas dashboard, click the “Create” button.
Choose “Serverless” as well as a cloud vendor where this instance should live.
If possible, choose a cloud vendor that matches where your application will live. This will give you the best possible latency between your database and your application.
Once you choose to click the “Create Instance” button, your instance is ready to go!
You’re not in the clear yet though. You won’t be able to use your Atlas serverless instance outside of the web dashboard until you create some database access and network access rules.
We’ll start with a new database user.
Choose the type of authentication that makes the most sense for you. To keep things simple for this tutorial, I recommend choosing the “Password” option.
While you could use a “Built-in Role” when it comes to user privileges, your best bet for any application is to define “Specific Privileges” depending on what the user should be allowed to do. For this project, we’ll be using an “example” database and a “people” collection, so it makes sense to give only that database and collection readWrite access.
Use your best judgment when creating users and defining access.
With a user created, we can move onto the network access side of things. The final step before we can start developing against our database.
In the “Network Access” tab, add the IP addresses that should be allowed access. If you’re developing and testing locally like I am, just add your local IP address. Just remember to add the IP range for your servers or cloud vendor when the time comes. You can also take advantage of private networking if needed.
With the database and network access out of the way, let’s grab the URI string that we’ll be using in the next step of the tutorial.
From the Database tab, click the “Connect” button for your serverless instance.
Choose the programming language you wish to use and make note of the URI.
Need more help getting started with serverless instances? Check out this video that can walk you through it.
At this point, you should have an Atlas serverless instance deployed. We’re going to take a moment to connect to it from application code and do some interactions, such as basic CRUD.
For this particular example, we’ll use JavaScript with the MongoDB Node.js driver, but the same rules and concepts apply, minus the language differences for the programming language that you wish to use.
On your local computer, create a project directory and navigate into it with your command line. You’ll want to execute the following commands once it becomes your working directory:
npm init -y
npm install mongodb
touch main.js
With the above commands, we’ve initialized a Node.js project, installed the MongoDB Node.js driver, and created a main.js file to contain our code.
Open the main.js file and add the following JavaScript code:
const { MongoClient } = require("mongodb");
const mongoClient = new MongoClient("MONGODB_URI_HERE");
(async () => {
try {
await mongoClient.connect();
const database = mongoClient.db("example");
const collection = database.collection("people");
const inserted = await collection.insertOne({
"firstname": "Nic",
"lastname": "Raboy",
"location": "California, USA"
});
const found = await collection.find({ "lastname": "Raboy" }).toArray();
console.log(found);
const deleted = await collection.deleteMany({ "lastname": "Raboy" });
} catch (error) {
console.error(error);
} finally {
mongoClient.close();
}
})();
So, what’s happening in the above code?
First, we define our client with the URI string for our serverless instance. This is the same string that you took note of earlier in the tutorial and it should contain a username and password.
With the client, we can establish a connection and get a reference to a database and collection that we want to use. The database and collection does not need to exist prior to running your application.
Next, we are doing three different operations with the MongoDB Query API. First, we are inserting a new document into our collection. After the insert is complete, assuming our try/catch block didn’t find an error, we find all documents where the lastname matches. For this example, there should only ever be one document, but you never know what your code looks like. If a document was found, it will be printed to the console. Finally, we are deleting any document where the lastname matches.
By the end of this, no documents should exist in your collection, assuming you are following along with my example. However, a document did (at some point in time) exist in your collection — we just deleted it.
Alright, so we have a basic example of how to build an application around an on-demand database, but it didn’t really highlight the benefit of why you’d want to. So, what can we do about that?
We know that pre-provisioned and serverless clusters work well and from a development perspective, you’re going to end up with the same results using the same code.
Let’s come up with a scenario where a serverless instance in Atlas might lower your development costs and reduce the scaling burden to match demand. Let’s say that you have an online store, but not just any kind of online store. This online store sees mild traffic most of the time and a 1000% spike in traffic every Friday between the hours of 9AM and 12PM because of a lightning type deal that you run.
We’ll leave mild traffic up to your imagination, but a 1000% bump is nothing small and would likely require some kind of scaling intervention every Friday on a pre-provisioned cluster. That, or you’d need to pay for a larger sized database.
Let’s visualize this example with the following Node.js code:
const { MongoClient } = require("mongodb");
const Express = require("express");
const BodyParser = require("body-parser");
const app = Express();
app.use(BodyParser.json());
const mongoClient = new MongoClient("MONGODB_URI_HERE");
var database, purchasesCollection, dealsCollection;
app.get("/deal", async (request, response) => {
try {
const deal = await dealsCollection.findOne({ "date": "2022-10-07" });
response.send(deal || {});
} catch (error) {
response.status(500).send({ "message": error.message });
}
});
app.post("/purchase", async (request, response) => {
try {
if(!request.body) {
throw { "message": "The request body is missing!" };
}
const receipt = await purchasesCollection.insertOne(
{
"sku": (request.body.sku || "000000"),
"product_name": (request.body.product_name || "Pokemon Scarlet"),
"price": (request.body.price || 59.99),
"customer_name": (request.body.customer_name || "Nic Raboy"),
"purchase_date": "2022-10-07"
}
);
response.send(receipt || {});
} catch (error) {
response.status(500).send({ "message": error.message });
}
});
app.listen(3000, async () => {
try {
await mongoClient.connect();
database = mongoClient.db("example");
dealsCollection = database.collection("deals");
purchasesCollection = database.collection("receipts");
console.log("SERVING AT :3000...");
} catch (error) {
console.error(error);
}
});
In the above example, we have an Express Framework-powered web application with two endpoint functions. We have an endpoint for getting the deal and we have an endpoint for creating a purchase. The rest can be left up to your imagination.
To load test this application with bursts and simulate the potential value of a serverless instance, we can use a tool like Apache JMeter.
With JMeter, you can define the number of threads and iterations it uses when making HTTP requests.
Remember, we’re simulating a burst in this example. If you do decide to play around with JMeter and you go excessive on the burst, you could end up with an interesting bill. If you’re interested to know how serverless is billed, check out the pricing page in the documentation.
Inside your JMeter Thread Group, you’ll want to define what is happening for each thread or iteration. In this case, we’re doing an HTTP request to our Node.js API.
Since the API expects JSON, we can define the header information for the request.
Once you have the thread information, the HTTP request information, and the header information, you can run JMeter and you’ll end up with a lot of activity against not only your web application, but also your database.
Again, a lot of this example has to be left to your imagination because to see the scaling benefits of a serverless instance, you’re going to need a lot of burst traffic that isn’t easily simulated during development. However, it should leave you with some ideas.
You just saw how quick it is to develop on MongoDB Atlas without having to burden yourself with sizing your own cluster. With a MongoDB Atlas serverless instance, your database will scale to meet the demand of your application and you’ll be billed for that demand. This will protect you from paying for improperly sized clusters that are running non-stop. It will also save you the time you would have spent making size related adjustments to your cluster.
The code in this example works regardless if you are using an Atlas serverless instance or a pre-provisioned shared or dedicated cluster.
Got a question regarding this example, or want to see more? Check out the MongoDB Community Forums to see what’s happening.
Original article source at: https://www.thepolyglotdeveloper.com/