Node.js with Domino a Tutorial

In my last blog I mentioned that I have been working with Node.js for a little while and wanted to share some of my education on the blog.  I thought a good way to do that would be to take an already existing tutorial application written for the MEAN stack(Mongo, Express, Angular, Node) and make it work with a Domino Database.

We are going to be looking at this

https://scotch.io/tutorials/creating-a-single-page-todo-app-with-node-and-angular

This is a great little tutorial that helps you write the obligatory todo app using node and Angular.  If you have little to no experience with Node or Angular, I highly recommend going through this tutorial.  But we are going to look at a couple parts of it and with very few modifications bind it to a Domino Database for its data instead of Mongo DB.

The first step in this process is to install Node,  I won’t go through the instructions as they are platform specific and are mentioned in detail in many places on the web.

Next we need to get the app in question, you can do that either by building out the tutorial or cloning down the git repository for the tutorial here:

git clone https://github.com/scotch-io/node-todo.git

This will put the app in the node-todo folder.

The next step is to connect it to a MongoDB which again you can get installation instructions all over the place.  Another option is to use a cloud hosted instance of Mongo.

The last step is to modify the config/database.js with your mongodb URL.

Once this is done you should be able to use the command line and in the node-todo folder call node server and your app will be up and running on port 3000.

I know I went over a lot very quickly in this post, but the goal is to get to creating a new component to bind this app to Domino.  If you have any questions about how any of this works or are having problems going through the tutorial, let me know and I’ll see if I can lend a hand.

In the next post I’ll describe a few of the working components so we have a good grasp of how they will interact with your Domino Database.

 

Advertisements

All the things….

I have not posted in way too long, thought I would dust off the blog and write a little.  I’ve been head down focusing on many new things since I last wrote, very few however have to do with XPages directly.  That being said I want to share all the things that I have been learning through this blog.  I have plans to put together a few posts on node.js as both a transition from being a Domino Developer and many of the best practices for development using this platform.  I also have been doing quite a bit of Native IOS development with Swift.  This is an amazing language that I hope gets used in other platforms now that it is open sourced.  I’d like to share some of my thoughts on server-side dev vs client side dev.  Oh and Docker, how Docker can make your life easier as a developer and an admin and a user, pretty much anyone.  Soon I hope to share all the things…

XPages on Bluemix is Live!

Its Live!  This morning after a long wait the XSP Buildpack and Domino Datasource became available on IBM Bluemix.  I’m so excited for this opportunity to use Domino on IBMs new PAAS.  I have many questions about how it is setup and how thing work.  I’m curious about how to deal with OSGI plugins and code outside of an NSF. I’m interested to find out how we can change the policy settings for the Security Manager on the JVM.  I have lots of questions but for now happy playing!

UPDATE

It doesn’t appear that the new extension library that will contain the Designer tools has been released yet.  I’ll let you know as soon as I know.  However you should be able to update your apps using the CF Command line tools.

Capture

JAX-RS or THE way to do REST in Domino Part 4

If you’ve ever created a REST service you know one of the first problems you’ll run into is that you can only call that service from the same domain that it lives on.  Because of Cross Origin Resource Sharing security issues, The browser will not allow it unless the service includes certain HTTP headers, namely headers that start “Access-Control-Allow” This information is explained in great detail on the Mozilla Developer Network site here.  In Domino adding these http headers to the response can be done differently based on what service you are using.  In XPages or in an NSF it can be done directly via a Phase Listener.  In DAS it can be sort of done by adding custom headers on the Domino Server Config.  It can also be done when writing a custom OSGI plugin.

In plugins you could write to the headers for each method that is specified in your resource, but most likely you want to write out the headers for everything that comes into your service.  The best way to handle it is with a Servlet Filter.  A Servlet Filter is some code that runs before the servlet that can manipulate the request/response and it runs on every request.

In our example we add this simple Servlet Filter


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CORSFilter implements Filter {

public CORSFilter() { }

public void init(FilterConfig fConfig) throws ServletException { }

public void destroy() { }

public void doFilter(
ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {

((HttpServletResponse)response).addHeader("Access-Control-Allow-Origin", "*");
((HttpServletResponse)response).addHeader("Access-Control-Allow-Credentials", "true");
((HttpServletResponse)response).addHeader("Access-Control-Allow-Methods", "POST");
((HttpServletResponse)response).addHeader("Access-Control-Allow-Headers", "Content-Type");
((HttpServletResponse)response).addHeader("Access-Control-Max-Age", "86400");

chain.doFilter(request, response);
}
}

It adds to the appropriate headers to every request that comes in and then delegates the request/response to the servlet.

The only other config change that needs to be made is to specify the filter in the web.xml


<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>com.tobysamples.demo.wink.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>

This puts a pattern on which urls will have the filter applied.  So as you can see this technique is simple and allows for complete flexibility as to what headers are sent down to the client.  So now you can build out your Domino Service and call it from other web apps.

JAX-RS or THE way to do REST in Domino Part 3.5

Soooo, I know I said the last segment was my last on this, but I thought I could share one other really cool thing about using JAX-RS.  Using JAX-RS allows you as a developer to avoid not only parsing JSON but also having intermediary objects like JsonJavaObject from IBM Commons.  It does this by allowing you to add in a mapper for both XML and JSON.  Which means you can have a model object that you develop and it will know how to translate it to and from JSON.

The basic tip is that you have to add one more method to your Wink Application Class, getSingleton.  This method basically lets you setup the mapper and add it to the framework.

The code to add this is as follows:


@Override
public Set<Object> getSingletons() {
Set<Object> s = new HashSet<Object>();
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary,     secondary);
mapper.getDeserializationConfig().setAnnotationIntrospector(pair);
mapper.getSerializationConfig().setAnnotationIntrospector(pair);
JacksonJaxbJsonProvider jaxbProvider = new   JacksonJaxbJsonProvider();
jaxbProvider.setMapper(mapper);
s.add(jaxbProvider);
return s;

}

For this code to work, you have to have in your classpath the jackson jar file.

Once you have added the jar file to your WebContent\Web-INF\lib\ folder

jackson

added it to the libaries tab in your Build Configuration

jackson3

you also need to add it to the Classpath Section in the plugin.xml under the runtime tab.

jackson2

Once you have that added to your class, now you can create Java classes and the framework will let you POST something like this:


{"fname":"Joe","lname":"User","email":"test@test.com","phone":"123.456.7841","birthdate":54544444}

at this method


@Path("/toby")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public MyBean postMessage(MyBean mybean) {
mybean.setFname("Toby");
return mybean;
}

The method gets the data and converts it to a MyBean object automatically then I change it and send it back to the client and it comes down as JSON all without me adding anything to handle the JSON, except for the annotations.

It’s pretty magical really.

Hope you get some mileage out of this info.

JAX-RS or THE way to do REST in Domino Part 3

In the last segment of this series I pointed you to use a couple of resources from  my github as templates, but didn’t really specify how those work or how to add your own services.  I hope to finish the series today with some explanation of those resources.

Web.xml

The Web.xml is the configuration in all Java EE apps.  It basically sets up the configuration for the application.  The application I have specified has a single servlet, which is defined by the wink framework.

org.apache.wink.server.internal.servlet.RestServlet

This servlet looks for a class of type “javax.ws.rs.core.Application”

So your application will need a class that extends it.  In the web.xml its specified in the init-param

<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.tobysamples.demo.wink.HelloWorldApplication</param-value>
</init-param>

The web.xml also has a servlet mapping basically specifies what url the servlet will live at.  In the example it is “/rest*/  which basically means if the url has that pattern in it it will call the servlet and pass in the rest of the url for routing.

HelloWorldApplication.java

This is the aforementioned class that is referenced in the web.xml.  The only thing it really does is overrides the getClasses Method and returns back a Set of classes that contain Resources which are basically the rest services that are defined.

HelloWorldResource.java

This is basically the meat of the service.  It specifies two methods one for a GET request annotated by the @GET above it and one for a POST request, annotated by the @POST above it.  So in this class we specify what URL it will live at with the annotation above the class declaration

@Path(“/helloworld”)

JAX-RS methods need to return a “javax.ws.rs.core.Response” object.  We are creating and returning this object in both of these methods, JAX-RS has some nifty functionality for sending back different http codes and http headers.  For instance you can see in the getMessage method I am returning back a 200 http status code with a content-type http header of application/json

ResponseBuilder builder = Response.ok(jjo.toString(), MediaType.APPLICATION_JSON);

JAX-RS is the standard way of doing REST services in the Java EE world, so there are all kinds of plugins and documentation/blogs out there with tips and tricks of how to use it once you have it setup.  I would recommend the java doc and the tutorial from Oracle on how to get started for some beginner lessons.  I know sometimes writing a xAgent or even a plain old agent is quicker, but to ensure that your code is decoupled and will even work outside of an XPages context this is probably your best way of creating a rest service.  Even IBM realized this as this is how DAS services is built in Domino.

JAX-RS or THE way to do REST in Domino Part 2

In part 1 of this series you learned how to setup Eclispe to write OSGi plugins.  Next we get to create a plugin.

1.  On the menu click File -> New -> Plugin Project

2.  Add your Project name and use Eclipse 3.4 Click Next

3.  Make sure Generate an Activator is checked, change Execution Environment to JavaSE 1.6, then Click Finish

4.  Your on the Overview Page of the Plugin, were going to start going through all the tabs on the Plugin, next click the Dependencies Plugin

5.  you’ll already have org.eclipse.core.runtime as a required plugin.  Go ahead and add com.ibm.pvc.webcontainer and org.apache.wink

6.  On the right side of the page add all the packages that use *org.apache.wink* and lotus.domino and javax.servlet.http, javax.servet, and javax.servlet.jsp. Next click on the Extensions tab at the bottom.

7.  Here you will add com.ibm.pvc.webcontainer.application

7a.  Change the contextRoot Details on the right to /myurlpath

7b.  Right-Click on com.ibm.pvc.webcontainer.application in the left window and add a new contentLocation, change it in the right window to “WebContent”

8.  In the package explorer add a new toplevel folder called WebContent, inside that folder add another folder called WEB-INF, and finally inside of that folder add a file called web.xml.

9.  Go back to the plugin.xml by double clicking on it.  then click on the Build Tab.  Check WebContent and bin folders to ensure they get included in the build.

10.  Next we can start updating the web.xml,  I have an example one in my project on my github here:

https://github.com/tsamples/jaxrsondomino/blob/master/WebContent/WEB-INF/web.xml

The web.xml points to the JAX-RS application we haven’t created yet, so you will also need to get the 2 Java files from the project here:

https://github.com/tsamples/jaxrsondomino/tree/master/src/com/tobysamples/demo/wink

Once you have added those 2 Java files and make sure the namespace matches what the web.xml has for it, you can fix the Activator.

In the previous Java folder there is also an Activator.  if you Overwrite the Activator you have in your project with that one, it will start up wink without any issues.  Consequently this was the strangest part of getting this working, Apparently wink needs this small bit of code in the start method of the activator to ensure that it runs in the right Thread context.  With all of that done you now should have a working Plugin, now you just need to deploy it.  Lots of ways to do this, you can use hot deploy PDE if you have it installed. or you can Right-Click and Export as a Deploy-able Plugin and Fragment, then drop the created jar in “C:\Program Files\IBM\Domino\data\domino\workspace\applications\eclipse\plugins” and restart the http task on your server.  The last and more production efficent way of deploying these is by using the updatesite.nsf.  But first you will have to create a Feature and UpdateSite project.  There are great directions to do all of the General OSGi stuff here:

http://www-10.lotus.com/ldd/ddwiki.nsf/dx/creating_an_xpages_library#Create+the+library+class

Once deployed the URL will be http://servername/myurlpath/rest/helloworld

If you have any questions please let me know.  I know there are a lot of steps here and sometimes things can get lost in translation.  But once you do a couple of these most of it is just muscle memory.  I hope to create a video outlying how to do this in an easier follow along manner.  If that would be useful to you please comment and let me know.