Editor's note: By Giuliano Iacobelli, Co-founder & CEO at Stamplay
Contents
Building The Backend
- Creating The App
- Creating A RESTful API For Posts
- Testing API End Points
- Registration & Login
- Indexing Posts On Algolia
- Adding Karma Points
Building The Frontend
- App Configuration & Setup
- User Registration & Sessions
- App Utilities
- Adding Posts
- Retrieving & Displaying Posts
- Using Query Params
- Comments & Upvotes
- Algolia Typeahead & Search
- Deploy!
Hacker News is a popular social news website focusing on computer science and entrepreneurship. If you’re a hacker or work in the startup space, you’ve almost certainly heard of it and perhaps even contribute to it!
Most front end developers often find themselves creating rich UI’s for their projects with frameworks like Angular and React but there comes a point where your app needs data, persistence, business logic, email and a whole host of other behaviours that are usually the domain of back-end developers. Stamplay is a service that aims to make these aspects of application development as easy as filling out a form.
Stamplay is a web-based development platform that gives developers an incredibly fast way to build fully integrated applications. Stamplay handles the trouble of talking to many different APIs for you so you don’t have to.
Stackshare users can try it now for free and benefit of an exclusive coupon to get 6 months free of Plus plan if they signup before Sept 30th and use the coupon code STAMPLAY_<3_STACKSHARE
when you upgrade your application’s plan in the editor dashboard.
In this tutorial we’ll show you how to glue together Stamplay, Algolia, and Mailgun APIs to build a clone of Hacker News. The app will feature the following functionalities:
- users can signup and login with email and password
- users can submit posts
- users can upvote and comment on posts
- users can earn points for comments and creating posts
- posts will be indexed in Algolia and users will have typeahead
- search users will receive a welcome email after they signup using the Mailgun API
Building the backend:
Creating the app
In the Stamplay Editor give your new app a unique name and then click the Create button. We’ve called our app hnews2.
You’ll now land on your dashboard for this app. Take note of this page as it has some important information for connecting our front-end to Stamplay.
Creating A RESTful API For Posts
We’re going to need “posts” if we’re going to have a hacker news-like app. Let’s go over to Stamplay and set up our Post Object before wiring it into our application.
On your app’s dashboard, click the Object link in the left hand menu then click + Add. Type post in the Object Name field then hit enter to start filling out its properties.
Testing API endpoints with the API Console
Stamplay has an API console that helps you to interact with your application. It let’s you perform API actions to get / set data and see how your application responds.
Let’s use the console to add our first post (we’ll add posts using our own app in just a moment). Click on API Console in the left hand menu of the Stamplay editor. From the Operation menu, choose “Create object”.
In the API URL field, choose “post” from the dropdown.
A form will appear asking for the properties of the Post you want to add. We’ll see the request as it’s sent to your app’s API, and eventually we’ll get a response. All going well, it should be a 200 OK.
Allowing users to Sign up / Login
On Hacker News only registered users are able to add new posts. Stamplay has already solved most of the user management lifecycle for us making signup and login very easy. Email+Password authentication is enabled by default.
Here you can also choose from a range of authentication solutions for your Stamplay application but in this demo we’re not going to use them.
Sending Email On User Registration
Let’s send a welcome email to new users and use the Mailgun API to do this.
Click on “Components” under “Tasks” in the Stamplay left hand menu, then select Mailgun component. Copy and paste on Stamplay the Mailgun domain and API Key that we can see on our Mailgun dashboard.
After this is connected let’s click on “Manage” under “Tasks” in the Stamplay left hand menu, then click “New Task”. We’re going to select: “When a user signs up, Mailgun – Send Email”.
Click “Continue” to get to Step 3 where you can use the values on the right to populate your email.
Click “Continue” once again, name the task and then let’s save it.
Indexing Posts on the Algolia Platform
As more and more posts get added to our app, it’s going to become impractical to use a simple list to choose and find interesting posts we’d like to read. So let’s use Algolia, a hosted search API (and the same one Hacker News actually uses), to implement a Typeahead search box that returns relevant results with just a few keystrokes. The service is fully integrated into Stamplay, but before moving forward you will need to create an Algolia account.
In the Stamplay Editor, we need to connect to Algolia. Go to the components, page and click Algolia. Enter your details (available on the credentials tab of your Algolia dashboard) and then click connect. We’ll need to create an index in Algolia. Algolia’s online app makes it easy to add an index and their tutorials are clear.
We’ll call our index “posts” – make sure that there’s no data (dummy data) in the index to begin with.
Now we can add a new task in Stamplay. From the criteria select: When a new Object is created, push data to Algolia.
On the next pages we’re going to select Post (the objects we want to search) and we’ll put them into our index named books.
We’ll index the title
property as title
, description
property as description
, the url
property as url
and the _id
property as postId
:
Note: any posts you’ve added before this point will not be indexed. Since we’re pairing the postId on Stamplay with the one stored by Algolia you might add another task to index them when they’re updated, or since it’s test data you can delete the older posts and add new ones. New posts you add will appear in your Algolia index.
Let’s say that we want to update Algolia records with the updated number of votes that posts have received. Let’s add a new task in Stamplay. From the criteria select: When a new Object is upvoted, update data to Algolia.
The first two steps are the same as the task we created before, the third one requires us to specify separately the objectId on the Algolia platform end.
Adding Karma Points:
User activity on Hacker News is rewarded with Karma points. We’ll implement this feature with a couple Tasks and CodeBlocks. We’ll award points to our users when they post a new content, or comment.
Create a Task, and set as "When an object is created, CodeBlock - Run Code".
On step two select the post instance to trigger on.
Set the Code As new_post
, you will select Type In A Custom Value from the dropdown to do this.
Configure the data field, to pass the _id
of our user who triggered this action to our Code Block.
Finally proceed and name the Task.
Before creating the Code Block for this Task setup another Task that triggers whenever a user comments on an post object.
Setup the new task as: "When an object is commented, CodeBlock - Run Code".
On step two select the post instance to trigger on.
Set the Code As new_comment
, you will select Type In A Custom Value from the dropdown to do this.
Configure the data field, to pass the _id
of our user who triggered this action to our Code Block.
Finally proceed and name the Task.
Now we can create our Code Blocks from this set of tasks that will give our user points for performing these actions.
Head over to Code Blocks and create a new one. Name the first new_post
just like we entered in the field in the task regarding new posts.
Inside this Code Block we will check if the user has a score already, and if they do we will add 100 points to it, otherwise set it to 100.
Our Code Block uses the Node.js SDK, which requires you add your APP ID
and API KEY
to the placeholders within the Code Block.
You can grab the code for copy here for easier configuration.
Save the Code Block after editing.
Our second Code Block will be exactly the same apart from being named new_comment
and the point value increase for commenting is 25 points instead of 100. But you can set the point values for the actions your prefer.
Now that the backend has been set up let’s move to the frontend!
Building the frontend:
The Stamplay CLI
In order to work with Stamplay we’ll need to connect our front-end app to Stamplay’s API. Stamplay has provided an npm package for this purpose. Go ahead and install the stamplay-cli package.
npm install -g stamplay-cli
App Configuration and Setup
Once the Stamplay CLI is installed, you can run stamplay init
in your project directory to generate a stamplay.json file.
You’ll need your app’s APP ID
and API KEY
both of which can be found on your app dashboard as mentioned above.
After we initialize our client side app with the stamplay init
command in our project directory, we will create our index.html.
Before we start coding, let’s install the required dependencies we will be using in our Hacker News clone:
Run the following bower command in your terminal:
bower install jquery jquery-Mustache mustache.js algoliasearch stamplay-js-sdk --save
After you have included the SDK, the other dependencies at the bottom on the your index.html, let’s get right to making the user login and registration components.
User Registration & Sessions
By default, email and password registration on the Stamplay platform is enabled. All we need to do is create an interface to submit the correct format of data, and properties into a method on the Stamplay User Model Object.
Sessions are also enabled by default. Sessions are automatically created when users log in or they sign up for an account. By default user sessions last 7 days.
When the session is created a token is generated and stored as x-stamplay-jwt
; since we are using the SDK we need not worry about including this token in our requests to Stamplay; but if you elect to use the Stamplay REST API, you need to include the x-stamplay-jwt
in the x-stamplay-jwt header of each request that requires a user to be signed in.
To get started on the user management portion of our app, in our login.html, create a login and a register form.
Now that we have our forms ready, let’s initialize our app inside the main.js file.
Adding Logic To Manage Users
At the top of our main.js file: Initialize the SDK in our app with:
Stamplay.init("<yourAppId>");
Create a variable named user that contains the Stamplay User Model;
After we have initialize the Stamplay SDK and the user model, we will create four methods to manage our users.
Register
Add an event listener to the form element with an id equal to signupForm
that will register a user on the submit event of the element.
The Stamplay.User.signup()
method at the top of our main.js file will take an object with a minimum of a email and password properties.
Login
Add an event listener to the form element with an id equal to loginForm
that will create a user session from the form credentials from said form, when the login form submit event is emitted.
The Stamplay.User.login()
method, also takes an object with the email & password password credentials to the login method.
For logging out a user, add an event listener to an element with an id equal to logout that will end a user session when the logout button is clicked.
To end the user session, just call the Stamplay.User.logout()
.
User Status
On document ready, retrieve the instance of the user currently logged in.
To get the currently logged in user, call the Stamplay.User.currentUser()
method on the SDK.
Inside our main.js we will set event listeners to grab the input for the corresponding function and call the method action we desire to be fired on the event we are listening for.
To test our app locally, enter the test command: stamplay start
, and visit localhost:8080
to debug.
Next we will add functionality to allow a user to add posts, upvote posts, and add comments to posts.
App Utilities
Throughout our app we will be using functionality such as formatting dates, parsing through url parameters, rendering data driven templates and separating the hostname from the full post url. To keep DRY, and focus on the important ports, lets create a few utilities to help these operations go more smoothly before we dive into creating posts.
Inside your, create these functions from utils.js to use later inside our main.js file.
Creating Posts
To create a new post we can take an object modeled after the schema(what we created eariler in the editor for post) and pass it to the save()
method on the SDK.
The steps to saving a new post are:
- Assemble an object modeled after the post schema.
- Call
Stamplay.Object("post").save(myPost)
to save the object as a post.
Inside our main.js we will set an event listener to grab the input, set each property on our ‘post’ model and call the save method on the model instance.
It is important to note that all asynchronous methods within the Stamplay JavaScript SDK return a promise. Each method’s promise is named then
which takes a pair of callbacks.
- The first is called when a promise resolves.
- The second is called when a promise is rejected.
These promises are also chainable, resolving in the order chained.
When the form above is submitted our post will be saved, and be added to the Algolia Index.
All we are responsible for is saving the post to Stamplay, then the Stamplay task we set up will manage the task of indexing the post on Algolia.
Remember, to test locally, run the stamplay start
command in your project directory and navigate to localhost:8080
to debug.
Viewing All Posts & Individual Posts
To fetch posts, we can use the get
method on the Stamplay JavaScript SDK.
Stamplay.Object.get()
will return the first 20 posts. Since we only want to view 10 at a time, and be able to paginate in the future we will setup query params to pass into the get()
method to filter, sort, and paginate our posts.
Configuring Query Params
To filter, and sort out the posts that we retrieve we will set multiple checks to change which query param is used in our getSortedPostList
function invocation.
To filter, and posts based on our location, and action we have configured the following functionality:
- If we are on the item page, we will retrieve just the post details for the id passed in.
- If there is url param newest we set the query param sort property to
-dt_create
. - This will return the posts in the order they were created.
- If search is found within the url, we set
queryParam._id
to equal the id parameter passed into the url.
We attach an event listener to an anchor with the id equal to morenews
, that when clicked increments the page queryParam
value by one, returning the next set of posts per page to our view.
main.js - queryParam
var page_param = (Utils.getParameterByName('page') === "") ? 1 : Utils.getParameterByName('page');
var queryParam = {
sort: '-actions.votes.total',
per_page: 10,
page: 1,
};
if (window.location.href.indexOf("item") > -1) {
getPostDetail();
} else if (window.location.href.indexOf("newest") > -1) {
queryParam.sort = '-dt_create';
} else if (window.location.href.indexOf("search") > -1) {
var _id = Utils.getParameterByName("id");
queryParam._id = _id;
}
getSortedPostList(queryParam);
$('#newest').css('font-weight', 'none');
$("#morenews").on("click", function(event) {
event.preventDefault();
queryParam.page += 1;
getSortedPostList(queryParam);
})
main.js - getSortedPostList
function getSortedPostList(queryParam) {
Stamplay.Object("post").get(queryParam)
.then(function(res) {
var viewDataArray = [];
var post_count = (queryParam.page - 1) * queryParam.per_page;
$('#newstable').html('');
res.data.forEach(function (post, count) {
var viewData = {
id: post._id,
count : post_count += 1,
url: post.url,
shortUrl: Utils.getHostname(post.url),
title: post.title,
dt_create: Utils.formatDate(post.dt_create),
commentLength: post.actions.comments.length,
votesLength: post.actions.votes.users_upvote.length
}
viewDataArray.push(viewData)
});
Utils.renderTemplate('list-elem', viewDataArray, '#newstable');
})
}
Inside the resolve callback of our promise, we iterate through each post on the post set in the response. This is where we will display the data, and link up the up votes for our users to interact with.
When we view, a single post, we can run the getPostDetail
function defined below to retrieve the details about that particular post.
main.js - getPostDetail
function getPostDetail() {
var postId = Utils.getParameterByName("id");
Stamplay.Object("post").get({ _id : postId})
.then(function(res) {
var post = res.data[0];
var viewData = {
id : post._id,
url : post.url,
shortUrl : Utils.getHostname(post.url),
title : post.title,
dt_create : Utils.formatDate(post.dt_create),
votesLength : post.actions.votes.users_upvote.length
}
Utils.renderTemplate('post-detail', viewData, '#postcontent');
post.actions.comments.forEach(function (comment) {
var viewData = {
displayName: comment.displayName,
dt_create: Utils.formatDate(comment.dt_create),
text: comment.text
}
Utils.renderTemplate('post-comment', viewData, '#postcomments');
})
}).catch(function (err) {
console.log('error', err);
})
}
Adding Comments & Upvotes
Next we will add comments, and upvotes to our post. First we will need access to the id of whichever post we are commenting on.
Once we retrieve the post we wish to comment on, which we may do by calling the fetch method on our post instance, passing in the id of the desired post to view.
To upvote a post, pass in the post _id to the Stamplay.Object("post).upVote(postId)
method.
To add a comment to our post, pass in post id and the comment text to the Stamplay.Object("post).comment(postId, commentText)
method.
Typeahead Search & Algolia
With typeahead and algolia, we will be able to search through the data on Stamplay, and return a list of items match your search.
Inside our main.js we setup the typeahead function to query algolia when we type a query into the search form inside our index.html. As we type, any matches to our current search will populate the suggestion field, providing our users a way to find content that matters to them without having to look through each post.
Deploy!
Now that we have used the various SDK methods to implement our app’s features, let's go live!
To deploy you stamplay app, type the stamplay deploy command at your project's root directory.
Add a comment when prompted for the deploy version, and your app will be live at: <yourappid>.stamplayapp.com
.
Stamplay offers a huge range of functionality with just a few lines of code, it lets the developer focus on making its app unique, skipping the parts that are somewhat patternized in development. If you prefer a more manual interaction with the services Stamplay provides, you may use the full featured REST API. For more information about the REST API, visit the documentation.
Don’t forget, Stackshare users can try it now for free and benefit of an exclusive coupon, STAMPLAY_<3_STACKSHARE
to get 6 months free of Plus plan if they sign up before Sept 30th, 2015!