Developing with the modern App Stack
MEAN and MERN (with Angular2 and
ReactJS)
Andrew Morgan @andrewmorgan
• Time to market • Iteration • Talent • Universal access • Responsive • Scalable • Highly Available • Loosely coupled REST APIs
Why do we care?
"JavaScript" & JSON { "firstName": "Ben", "lastName": "Dixon", "country": "UK", "dependents" : [ { "name" : "Ben", "birthday" : "12-Apr-1994" }, { "name" : "Erik", "birthday" : "05-Jul-2005" } ], "birthday" : "02-Jul-1964", "salary" : 50000, "skills" : [ { "skill" : "MongoDB" }, { "skill" : "Node.js" } ] }
ES6 classes
modules promises
iterators
generators typed arrays
Typescript static type checking
JSX
Java Script
• Blog series: https://www.mongodb.com/blog/post/the-modern-application-stack-part-1-introducing-the-mean-stack
• GitHub Repos: • https://github.com/am-MongoDB/
MongoDB-Mongopop • https://github.com/am-MongoDB/
MongoDB-Mongopop-ReactJS • https://github.com/am-MongoDB/
MongoDB-Alexa
Resources
Node.js
• JavaScript runtime environment • Application back-end (within Express) • Built-in features such as HTTP • Asynchronous
• Call-back functions • Promises • Observables
• npm package installer & package.json > npm install mongodb
MongoDB
Scalability & Performance
Always On, Global Deployments
Flexibility Expressive Query Language & Secondary Indexes
Strong Consistency
Enterprise Management & Integrations
Automated Available On-Demand
Secure Highly Available Automated Backups
Elastically Scalable
MongoDB Atlas
REST API
• REpresentational State Transfer • It's how clients talk to app back-ends • It's how services talk to services • HTTP(S) • METHOD conventions:
• GET: Fetches data • POST: Adds new data • PUT: Updates data • DELETE: Removes data
Express
• Runs back-end (JS) application • Node.js module • Terms:
• route: relative path to a part of the application • view: templates from which HTML pages are rendered • view engine: middleware to render views
• 2 Extremes: • Render entire page in Express • Provide nothing but REST API to access resources
Express routes
• app.js: var pop = require('./routes/pop'); app.use('/pop', pop);
• routes/pop.js router.get('/ip', function(req, res, next) {
// Sends a response with the IP address of // the server running this service. res.json({"ip": publicIP});
});
Angular 2 • Front-end • Reactive • Components • Services • Typescript
• tsc • Data flows down • Events back up • Boilerplate files • Mobile Apps:
• NativeScript, Ionic, or Ionic2
Execution flow index.html: <script src="systemjs.config.js"></script <body> <my-app>Loading MongoPop client app</my-app> </body>
app.component.ts: @Component({ selector: 'my-app', templateUrl: 'app/app.component.html', styleUrls: ['stylesheets/style.css']}) onCollection(CollName: string) { this.MongoDBCollectionName = CollName;}
app.component.html: <my-add [dataService]="dataService" [MongoDBCollectionName]="MongoDBCollectionName" [MockarooURL]="defaultMockarooURI" (onCollection)="onCollection($event)"> </my-add>
Execution flow add.component.ts: @Input() dataService: DataService; @Input() MongoDBCollectionName: string; @Input() MockarooURL: string; @Output() onCollection = new
EventEmitter<string>(); this.onCollection.emit(this.MongoDBCollectionName);
add.component.html: <p> Collection name: <input #MongoDBCollName id="MongoDB-collection-name" value="{{MongoDBCollectionName}}"/> </p>
ReactJS • Front-end • Reactive • Components • Services • JSX
• babel • Build optimized package for production
• Data flows down & events back up • Boilerplate files (fewer) • Mobile Apps:
• React Native
Component data flow
• Components inherit data as properties
• Components store own data to be rendered as state • setState()
• Handler functions passed down to pass changes back to parent
Execution flow index.html: <div id="root"></div>
index.js: import App from './App'; ReactDOM.render( <App />, document.getElementById('root'));
Execution flow App.js import { CollectionName } from './collection.name.component'; class MongoPopContainer extends React.Component { handleCollectionChange(collection) { this.setState({MongoDBCollectionName: collection}); } render() { return ( <CollectionName dataService={this.dataService} onColl={this.handleCollectionChange} /> )} } class App extends Component { render(){return ( <MongoPopContainer />)} }
collection.name.component.js: handleCollectionNameChange(event) { this.setState({collection: event.target.value}); this.props.onColl(event.target.value); } render() { return ( <label> Choose the collection: <input type="text" size="20" value={this.state.collection} onChange={ this.handleCollectionNameChange} /> </label>) }
Amazon Alexa
Intents:
{ "intents": [ {"intent": "WhereIntent"}, {"intent": "CountIntent"}, {"intent":
"AMAZON.HelpIntent"}, ] }
Utterances: WhereIntent where is andrew WhereIntent where is he WhereIntent where am I WhereIntent where did he last check in WhereIntent where did Andrew last check in WhereIntent where did i last check in WhereIntent last check in
CountIntent how many checkins CountIntent how many times have I checked in CountIntent how many times has Andrew checked in CountIntent how many times has he checked in CountIntent how many check ins CountIntent check in count