Create Micro-Services Using Java and the Spark Java Framework

Document created by fmpdude on Jan 17, 2018Last modified by fmpdude on Feb 24, 2018
Version 48Show Document
  • View in full screen mode

Since problems have been reported with FMS and installed Java versions, please be careful with Java and FMS using this tutorial. There are warnings in the tutorial below. Additionally, the code below is not intended to be production ready, just another example showing how to drastically enhance the power in FMP.

 

---------------

 

This tutorial would not have happened or have been as good without the help of a couple great folks here on the forum. I want to thank beverly for her edits, suggestions, being a terrific sounding board, and just in general for her terrific attitude. I also want to thank PeterDoern for his initial interest in the micro-service tutorial and his encouragement that I write this tutorial in the first place.

 

INTRODUCTION TO MICRO-SERVICES

(Approximate reading time: 30 minutes.)

 

Micro-services are small Representational State Transfer (REST) web services that listen for and respond to HTTP requests (examples include GET, POST, and PUT). Since micro-services listen for generic HTTP Requests, they are not product or vendor specific. That’s a good thing! Therefore, any application that can issue HTTP verbs could (probably) use a micro-service. Check the documentation for each application you use to see if they can issue HTTP verbs. Using micro-services helps you avoid vendor “lock-in” since you own the functionality.

 

This tutorial explains how to install Java, install a Java Integrated Development Environment (IDE), and configure a basic micro-service using the “SparkJava” framework. Once loaded, you could call the micro-service from any program that could issue HTTP verb requests.

 

SparkJava is a free and open-source software web application framework and domain-specific language written in Java.  You can see statistics of how people use SparkJava on their website. From that survey, about 15% of those users have deployed SparkJava applications (or services) that serve over 10,000 users per day!  (see: http://sparkjava.com/).

 

This tutorial explains how to call a micro-service from: POSTMAN, the terminal, FileMaker Pro, and the browser. This tutorial also explains how to create an HTTP GET micro-service method (“method” … think: “function”) and then how to call it.  Although similarly handled in code, this initial tutorial won’t cover POST and other HTTP Request methods.

 

Although you can use Terminal for testing most Requests, it's a good idea to download a helpful program like POSTMAN where you can issue test Requests against your web service methods before implementing them in whatever third-party program you’re using (for example, FileMaker Pro, Visual FoxPro, etc.).

 

The goal for this tutorial, then, is to setup a micro-service you can either run from the Java programming environment itself (that is, the IDE) or from a standalone “JAR” file  (Java ARchive is a package file format with the same internal format as a zip file). This tutorial discusses how to set up standalone JARs later.

 

WHY TAKE THE TIME TO LEARN MICRO-SERVICES?

As you write the micro-service logic, you take advantage of the virtually unlimited Java libraries—already tested/debugged/free and ready to go—for your application. If you need new functionality, there’s probably already a library available. Just include that library in your micro-service project and you have brand new functionality.  Many libraries will also let you programmatically “extend” them so you can leverage what’s there but add or modify it to suit your needs. Java has been the #1 programming language for more than a decade so help is never far away. Java is fast, free, and easy to learn.

 

Bottom line: with micro-services you write, features you need today are most likely available …today! There may be no reason to wait for some future version of FileMaker or other product when you can do what you need to do now.

 

Additionally, your micro-service, once written, can run on your computer, it can run on a file server, it can run on a cloud server….it can run…anywhere that’s accessible!  Best yet, other REST-enabled applications (for example, Terminal, Browser, and other REST-enabled applications) can probably use your micro-service too!

 

FILEMAKER FORUM POSTINGS USING MICRO-SERVICES

To answer applicable forum questions, and, here, to motivate learning micro-services, below are a few of my forum postings. For these postings, I created the (normally quick and easy) micro-service code (a function or “method”) and then created a FileMaker application that used the micro-service.

 

    1.    Extract Text From Word Documents

    2.    Read/Search Excel Workbooks/Spreadsheets (xls, xlsx)

    3.    Compute Days Between Dates with (Optional) Custom Holidays

    4.    Get Day Of Week For Date

    5.    Get Week Number for Date

    6.    Sending A Path To A URL To Call A Web Service

    7.    Extract Domain including Sub-Domains from URL

    8.    Extract Just the Domain Name Given URL

    9.    Get External IP Address (public IP)

    10.    URL Encoding/Decoding

    11.    Sorting Numbers Using External Rest Service (Spark Java)

    12.    Call A File Dialog From FMP

    13.    RSA Encryption with Per User Key Management

    14.    SHA 512 Hash Implementation with Salt

    15.    Using Regex From FMP

    16.    URL Checker (actual live check for URL validity)

    17.    FileMaker Integration with R Statistics Program —> 

               Create Poisson Statistics Using Two Different Techniques From R (Including Excel's Cumulative True Or False)

    18.    Excel’s Rate Function

    19.    Format ExecuteSQL Timestamps

    20.    Extract Strings To Create HREF Within Surrounding Text Delimited Using Double Delimiters

    21.    TimeZone EST -» UTC

    22.    TimeZone Current Time in Other Zone

    23.    GMT TimeZone offset From Zone

    24.    Time in Other TimeZone for Future Date

    25.    Implement The Excel Rate Function Using Micro-Service

    26.    Find Missing Values

    27.    Format Field To Indicated Decimal Precision

    28.    Generate QR Code (Read/Write)

    29.    Process JSON Using Industry Standard APIs

    30.    Generic Date and DateTime Conversion

 

URL FORMAT

 

From Terminal, FileMaker, or the Browser, you will issue a command like this:

 

http://localhost:4567/HelloWorld

 

EXPLANATION

 

localhost” means the local computer. But, instead of “localhost”, you could have a domain name, or even an IP address. Thus, the micro-service could be running on your computer or on a server anywhere. Note: you can use either localhost or 127.0.0.1.

 

4567” is the port on which the service is listening. This default port (4567) is easy to change in the micro-service you are writing or maintaining. You can find the documentation how to change the port, if necessary, on their site (http://sparkjava.com/index.html). Good news: changing the port number is a single line of code.

 

/HelloWorld” is the method we’re calling (which has the Java code we want to run). A “method” is like a “function” in other programming languages though, unlike a function, a (“void”) method is not required to return a value.

 

You can also, and usually will, pass parameters. This tutorial will show basic parameter passing for a GET request. You can see how to handle parameters, in more detail, on the SparkJava website.  (http://sparkjava.com/documentation#routes)

 

CONFIGURATION

 

Although micro-services are straightforward to use, the basic setup of all the components can be initially challenging. If you've never set up a Java IDE or installed a Java Development Kit (JDK), these tasks will probably seem foreign. Although none of these tasks is particularly difficult, the initial configuration takes time and patience.

 

This quick tutorial will explain some configuration items, but usually points you to various resources to get you started. Some trial and error would be expected getting everything installed and set up.

 

To help you with configuration challenges you run into, there are plentiful online resources, including forums where you can post messages (for example, IntelliJ support) and get help. See the RESOURCES section at the end of this tutorial for more info.

 

If you receive an error or warning message when you write your micro-service, that error message will normally be Java related. A good first step is to search the web with that exact error message and you’ll often find the answer quickly. Also, consider joining a free Java help forum to post questions. StackOverflow is another terrific resource for all questions technical.

 

DEPENDENCY

 

As with using a plug-in or similar software, using an external framework like SparkJava adds a dependency to your project. That is, the service must be running and be reachable before you can make calls to it. The service can be running locally, on a server, or anywhere on the Internet. Some firewall configuration may be necessary. (More on how to start the service later.)

 

DO I NEED TO KNOW JAVA?

 

Yes. Micro-services using the SparkJava framework use Java. However, Java is a friendly language so you can pick it up a little at a time. Note that beyond setting up the initial HelloWorld micro-service, this tutorial won’t attempt to explain how to program in Java (a huge subject itself). Thus, you can learn Java as you go along, take a class, join Java forums, watch videos, get a book or two and enjoy the journey. Java is an amazing language which is deep, rich, and at times, complex.

 

INSTALL JAVA 8

 

Warning: If you are concerned that a version of Java might interfere with an “expected” version of Java for some application or server application (for example FMS), consider using a separate machine for this tutorial or consider creating a virtual machine so you have a separate environment. (Note that the IDE itself lets you freely switch between Java JDK versions.)

 

One of the first things you need to do is install the Java 8 JDK. You need at least version 8 for the SparkJava framework. At this writing, Java 9 is due to be released. No testing has been done with Java 9 beta builds.

 

To download Java 8, agree to the license on that page and click to download the Java 8 version for the operating system you have and wait for Java to download. Once you have downloaded Java at the URL below, run the installation file to install Java on your computer.

 

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

 

To test that Java was correctly installed, you can open a terminal window and type “java -version” as shown below. You should see output similar to what is below though your actual version number might be different.

 

$ java -version

java version "1.8.0_144"

Java(TM) SE Runtime Environment (build 1.8.0_144-b01)

Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

 

Now that you have installed Java JDK 8, you are ready to install the IDE. This tutorial uses IntelliJ IDEA. IntelliJ is a Java “Integrated Development Environment”. Thus, IntelliJ has all the tools you need to write cool Java code, debug it, refactor it, format it, and more. This is an amazing and very deep programming tool that has capabilities you continue to learn and master over time.

 

INSTALL JETBRAINS INTELLIJ IDEA

 

JetBrains has a free community edition of IntelliJ IDEA, but this tutorial assumes you have installed the “Ultimate” version. This “Ultimate” version has a free evaluation.

 

You can find IntelliJ here: https://www.jetbrains.com/idea/download/#section=mac

 

You should automatically be on the right download page for your operating system, but if you want to download another operating system’s version of the IDE, you should see the three choices from the download page link above.

 

 

Download and install IntelliJ and get ready for the next step.

 

CONFIGURE INTELLIJ FOR YOUR VERSION OF JAVA

 

After installing IntelliJ, you will need to tell it where your Java JDK files are that you installed earlier. You can find many resources online to help you with this initial configuration for IntelliJ. (See the RESOURCES section at the end of the document for a YouTube video that will help.)

 

A typical directory to find the JDK files, after installation (on mac) would be similar to this:

/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk

 

CREATE A NEW MAVEN (JAVA) APPLICATION AND CONFIGURE

 

To setup and configure your project for SparkJava, follow the steps here (for IntelliJ IDEA):

 

http://sparkjava.com/tutorials/maven-setup

 

(after doing these steps, you’re almost done!)

 

Note that if you prefer the free Eclipse Java IDE, use the link below which has instructions to set up Eclipse. This tutorial covers IntelliJ, but the same overall configuration applies to both IDEs.

 

For Eclipse IDE, use this link:

 

http://sparkjava.com/tutorials/maven-setup#eclipse

 

ADD HelloWorld GET METHOD

 

When you create a Maven project in the IDE, Maven uses a pre-defined project directory structure src/main/java. That pre-defined project structure is how Maven does its build magic.

 

When you’re done with the setup from either of the sparkjava links above (IntelliJ or Eclipse), you should have a Main class with method with this code:

 

public class HelloWorld  // must be in a file called “HelloWorld.java”

{

    // main method is the entry point into the application

    public static void main(String[] args)

   {

        get("/helloWorld", (req, res) -> "Hello World");

 

       // other methods here…

 

    } // end main

 

} //end class

 

RUN THE SERVICE FROM THE IDE

 

To run the micro-service from the IDE, you can click the little green ">" next to the "public void static main(String [] args" in the code

 

or you can click the green ">" in the toolbar.

 

When you run the service, you'll see output in the output window similar to this (you may not see as many lines shown, that’s OK as long as you don’t see an error code):

 

objc[39701]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java (0x10d5194c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10d5e14e0). One of the two will be used. Which one is undefined.

[Thread-0] INFO org.eclipse.jetty.util.log - Logging initialized @519ms to org.eclipse.jetty.util.log.Slf4jLog

[Thread-0] INFO spark.embeddedserver.jetty.EmbeddedJettyServer - == Spark has ignited ...

[Thread-0] INFO spark.embeddedserver.jetty.EmbeddedJettyServer - >> Listening on 0.0.0.0:4567

[Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.4.4.v20170414

[Thread-0] INFO org.eclipse.jetty.server.session - DefaultSessionIdManager workerName=node0

[Thread-0] INFO org.eclipse.jetty.server.session - No SessionScavenger set, using defaults

[Thread-0] INFO org.eclipse.jetty.server.session - Scavenging every 660000ms

[Thread-0] INFO org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@145f3f76{HTTP/1.1,[http/1.1]}{0.0.0.0:4567}

[Thread-0] INFO org.eclipse.jetty.server.Server - Started @785ms

 

Note that the program hasn't ended with any response code. Thus, you know the service is now running, which is what you want. To stop the service you could either close the IDE, click the "Run" menu and select "Stop <your app name>", or click the red square in the bottom of the IDE:

 

 

TESTING CALLS TO THE SERVICE

 

————————————

POSTMAN

(https://www.getpostman.com/)

————————————

 

    Good idea to try POSTMAN first. With simple Requests, you might go straight to Terminal (next example).

 

————————————

TERMINAL

————————————

 

    With Terminal use the "curl" command. GET is default so you don't need any command-line arguments.

 

$ curl localhost:4567/helloWorld

 

Hello World.

 

————————————

FILEMAKER PRO

————————————

 

    For FileMaker, we use the same URL, except we don't need CURL. All we need to do is create a single INSERT FROM URL script step and enter the same information as the Terminal example above. (Note: Code tested with FMPA 14 and 16)

 

 

Then set up a simple layout where the command button calls the one-line INSERT FROM URL script above and see that we get the same result as with Terminal and POSTMAN.

 

 

You can also make calls to the web service from focus or from other events on layouts.

 

(As shown later in the tutorial, you can include field values as parameters to the web service methods.)

 

————————————

THE BROWSER

————————————

 

Typing: http://localhost:4567/helloWorld

 

In the browser, the same URL gives you….

 

CREATE AN EXECUTABLE JAR FILE OF THE SERVICE

 

An executable JAR file (aka: “FAT JAR”) is a single file with all the project dependencies (other than Java itself) inside the JAR file. A JAR file has the same internal format as a ZIP file. Thus, the JAR file “is” the service. Maven manages project dependencies each time you build the JAR file. Thus, Maven adds all needed dependencies (libraries, etc.) to the JAR. Need something new in the project (like some library)? Find the Maven dependency online (or IntelliJ will also code complete the tag information for you right inside XML tags - even if those tags have quotes!).

 

See the RESOURCES section at the end of the tutorial for a Maven link to YouTube.com.

 

To create an executable JAR from your micro-service plug-in, you add a section to your maven pom.xml.

 

Here's an example Maven build goal (your values might vary):

 

<plugin>

    <artifactId>maven-assembly-plugin</artifactId>

    <version>3.0.0</version>

    <configuration>

        <descriptorRefs>

            <descriptorRef>jar-with-dependencies</descriptorRef>

        </descriptorRefs>

        <archive>

            <manifest>

                <mainClass>sparkdemo.HelloWorld</mainClass>    // whatever your Main class is called.

            </manifest>

        </archive>

    </configuration>

    <executions>

        <execution>

            <id>make-assembly</id>

            <phase>package</phase>

            <goals>

                <goal>single</goal>

            </goals>

        </execution>

    </executions>

</plugin>

 

Once you add this goal to your Maven configuration, you can click the "install" option (under Lifecycle) in the maven build and build a JAR file. (See "Maven Projects" in the right tab, far right side - of the IDE.)

 

If you run into problems, read the documentation online for more information.

 

OTHER DEPLOYMENT OPTIONS

You could optionally create a “WAR” file so your service would not need to be run from the command line in a Terminal window. Deploying to an application server means your service is always running when the application server is up — without you having to explicitly start it as we’re doing here.  Simply stated, however, a WAR file is deployment file type for an application server like Tomcat.

 

So, assuming you deployed your services (WAR file) to an application server like Tomcat, you can then still use them as you did before. Tomcat’s default port is 8080, so you might have a URL like the one below (assuming we wrote a method to compute days in future or past from entered date):

 

http://localhost:8080/services/dateMath//2017-12-27/30

 

Output in browser: 2018-01-26

 

(A detailed discussion of WAR files and how to configure them is beyond the scope of this document. If interested, check the Maven documentation.)

 

RUN THE SERVICE JAR FILE FROM THE COMMAND LINE


Once you have an executable JAR file built, copy it to some directory for testing (you can drag the JAR file directly from the IntelliJ project to wherever you wish). Then, "CD" into that directory in a Terminal and start the JAR file, like this (assuming you named your JAR file HelloWorld.jar):

 

$java -jar ./HelloWorld.jar

 

You should see the same output as you saw in the IDE as the micro-service starts up:

 

$ java -jar ./HelloWorld.jar

[Thread-0] INFO org.eclipse.jetty.util.log - Logging initialized @238ms to org.eclipse.jetty.util.log.Slf4jLog

[Thread-0] INFO spark.embeddedserver.jetty.EmbeddedJettyServer - == Spark has ignited ...

[Thread-0] INFO spark.embeddedserver.jetty.EmbeddedJettyServer - >> Listening on 0.0.0.0:4567

[Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.4.z-SNAPSHOT

[Thread-0] INFO org.eclipse.jetty.server.session - DefaultSessionIdManager workerName=node0

[Thread-0] INFO org.eclipse.jetty.server.session - No SessionScavenger set, using defaults

[Thread-0] INFO org.eclipse.jetty.server.session - Scavenging every 660000ms

[Thread-0] INFO org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@48d69dfe{HTTP/1.1,[http/1.1]}{0.0.0.0:4567}

[Thread-0] INFO org.eclipse.jetty.server.Server - Started @387ms

 

 

Note that the Terminal appears to be "hung" since you didn't get your prompt back. However, this is the same behavior you saw in the IDE and just means the service is running and listing for requests. To stop the service, just close the Terminal window.

 

You can now repeat the tests we did when we ran the service from the IDE (POSTMAN, Terminal, FileMaker, and the Browser) and you should get the same results.

 

ADDING OTHER METHODS (FUNCTIONS)

 

To add more functionality to your micro-service, you just add more methods. You identify methods by the method signature.

 

So….

 

     get("/helloWorld", (req, res) -> "Hello World");

 

is a different method than

 

    get("/hello", (req, res) -> "Hello World");

 

 

So, the "signature" is the first part inside the parenthesis. You also need to match the GET, POST, PUT, or however you will call the service, too. Thus, GET, POST, PUT, etc., are also part of the signature.

 

HOW DO I DEBUG THESE SERVICES?

 

As mentioned above, Micro-services are regular Java applications. Thus, these services are much simpler to debug than a standard web service (Note: debugging regular web services is beyond the scope of this tutorial). In particular, since regular Java applications have a “main” method, you can run them from the command line. As discussed earlier, when you start the service, it runs but doesn’t quit (until you shut it down) so that it can listen for requests.

 

OK, let’s say you want to debug a method in your service called “hello”. How would you do it?

 

In IntelliJ, you click on the left margin of your editor and you’ll see a little red circle as you see below:

 

Then, start the service using the debug button on the toolbar:

 

 

And, when the service is running in debug mode, your red circle becomes a red circle with an internal check mark as you see below.

 

 

(Note, if you see an “x” in the circle, that means you put the debug point on a non-executing line of code. Just move the debug point.)

 

Now, to actually test the breakpoint, let’s call this method from Terminal and inspect the variables passed.

 

 

Now, in the IntelliJ debugger, we can inspect, in this case, the parameters passed (see the next section for an introduction to parameter passing to SparkJava micro-services).

 

A partial screenshot of the debugger is below after we stopped on the breakpoint.

 

In the debugger, we can do powerful things you might not have seen in other environments. Examples: you can set the value of a variable to a new value (in the currently running program!), you can copy a variable’s value, do other ad-hoc inspections, add a variable to a “watch”, and other useful things. IntelliJ is extremely mature and powerful and you’ll continue to learn more about it, or whichever IDE you choose, over time.  Observant readers may have noticed that in the source code (top middle pane), the IDE presents the actual variables’ values inline in the code!

 

Using the debugger in Eclipse, or other, IDE uses similar steps as shown above. Regardless which IDE you use, being able to easily debug your service is one of the many great things about micro-services.

 

CALL TO WEB SERVICE AND OUTPUT:

 

$ curl localhost:4567/hello/fmp/dude

 

Hi ya, fmp dude

 

(Extra Info: there are also many free IDE plug-ins (most, if not all, are free). “PMD” for example will search your code for coding problems and suggestions for improvement, as will “FindBugs”.)

 

FIVE MORE REALISTIC EXAMPLES

 

(1) USING REGULAR EXPRESSIONS FROM FILEMAKER

 

In the screenshot below, as posted on the FM Forum, in the first column you see the string on which we wish to apply a regular expression. The second column has the regular expression we will apply. The third (highlighted) column, shows the behind-the-scenes GetAsUrlEncoded() function results. The final, fourth, column, has the RegEx result the micro-service returned.

 

 

The full list of Regular Expressions, from numerous forum postings, in the sample FileMaker Application above is:

What is important with the micro-service implementation is that the user doesn’t have special “setup” tasks other than know the regular expression needed. The micro-service did all the RegEx work behind the scenes (highly “abstracted”) and away from the user.

 

Abstraction is a good thing.

 

To call the micro-service RegEx method, we need exactly one one of FileMaker code (after we URL-encode the string):

 

Thus, whenever some implementation bleeds through to the interface (where the user, for example, is forced to do special setup or other tasks), that’s often a sure sign things could be better abstracted.

 

Adding RegEx to FMP was surprisingly easy and only took a few lines of code!

 

(2) ZIP CODE LOOKUP

 

This example uses the freely-available zip code database from here: http://federalgovernmentzipcodes.us/

 

Note that this zip code database may not be complete or totally accurate and is only used as an example. You can find other CSV zip code resources as well online (free and paid).

 

Step 1: We import that database into our favorite database server (can be any database server) manually or programmatically.

 

Step 2: Once we have imported the CSV into the database server of our choice, we get the data in our micro-service using the free JDBC driver for that database (FileMaker, MySQL, SQL Server, Oracle, and most others have free JDBC drivers you can find online. FileMaker’s JDBC driver is in its installation distribution).

 

Step 3: We then write some JDBC logic, in Java (not shown), to process the results (a “ResultSet”) after sending the SQL to the database server. In this case, we send SQL to return the fields below -- see screenshots -- using the entered zip code.

 

    Note: JDBC is a driver you download and make available to your micro-service project so it can connect to the database.  Changing your JDBC logic to work with another database vendor is often as simple as changing the JDBC connection in the code (or, more commonly in production, via a configuration file).

 

Step 4: Once we have the data returned from the database, we then process the data and return it in a format that’s usable for the calling program. In this case, for FileMaker we return a return-delimited list so it’s easy to process into fields from a script.

 

Let’s first make sure the micro-service works from POSTMAN before diving into FileMaker:

 

Here’s a POSTMAN test for zip code 93591:

And, here’s another POSTMAN test for FileMaker home, Santa Clara, CA:

 

Finally, integrating this web service (micro-service) into FMP is easy since all we need to do is call the service the same way as you see in the two POSTMAN examples above, and then process the result using GETVALUE() into fields. (Remember, we took special care in the micro-service to return data in the best format for the caller. FileMaker in this case.)

 

Data Returned and Processed in FileMaker (using a Raspberry Pi as our service’s server)

Processing GetValue() in FileMaker depends on how you structured the data in the micro-service. Since I used this format: Data Label then a NEWLINE, then the data then a NEWLINE (etc), I know that every data item is a multiple of two. The service returns the data labels, but for this example, we’re ignoring them.

 

Thus, the super simple example script* looks like this (note, you would need to substitute the actual IP address of your Raspberry PI (or other) server. Or, you could use “localhost” if service is running on the same computer:

Insert from URL [ Select ; With dialog: Off ; $data ; "IP_ADDRESS_OF_SERVER:4567/zipcodeLookup/" & ZipCodeLookup::ZipCodeEntered ]

 

Set Variable [ $counter ; Value: 0 ]

Set Field [ ZipCodeLookup::ZipCode ; GetValue ( $data ; 2 ) ]

Set Field [ ZipCodeLookup::City ; GetValue ( $data ; 4 ) ]

Set Field [ ZipCodeLookup::State ; GetValue ( $data ; 6 ) ]

Set Field [ ZipCodeLookup::Lat ; GetValue ( $data ; 8 ) ]

Set Field [ ZipCodeLookup::Lon ; GetValue ( $data ; 10 ) ]

Set Field [ ZipCodeLookup::EstPop ; GetValue ( $data ; 12 ) ]

 

(Note: FMP 16's Results to Variable ooption comes in handy in the INSERT FROM URL command.)

——

 

*You may have correctly noticed that this script only processes one zip code entry in the “$data” variable. In your actual application, you’d to potentially process multiple zip code entries (depending on zip code — see the example above for zip code 93591) and add records to FileMaker as needed.

 

For Santa Clara, however, we’re good (no extra rows to process), as there’s only one zip code for it.

 

From the FMP Debugger:

 

Now, sure, you could have done this zip code lookup example using only FileMaker, but this is an example of a service (which in this case just happens to be database driven).

 

A key point with micro-services is we can also use them from other applications!

 

For example…

 

Terminal:

$ curl localhost:4567/zipcodeLookup/90210

 

Gives us…

Zip

90210

City:

BEVERLY HILLS

State

CA

Latitude

34.09

Longitude

-118.41

Estimated Population

16984

 

Browser:

 

Gives us…

 

Say you use KeyBoard Maestro to automate various tasks on your Mac. With just one macro line (Get URL), you can call your micro-service and get the same results:

 

Keyboard Maestro:

 


(3)  COMPUTE DISTANCES USING ZIP-CODE DATA WITH LAT/LON

 

Free and paid zip code data includes Latitude and Longitude data. Using the simple Haversine formula as a good approximation for distance, we can easily compute the distance between two points, and even get the distance in the desired units (Miles, Kilometers, and Nautical Miles), too.

 

Our service requires five parameters:

    1.    Starting point latitude

    2.    Staring point longitude

    3.    Ending point latitude

    4.    Ending point longitude

    5.    Distance type: M: Miles, K: Kilometers, N: Nautical Miles

 

Example: We need to ship something from New York (Manhattan) to Miami-Dade. How far is that?

 

Our URL looks like this for another service we have running:

 

http://192.169.0.1:8080/services/computeDistanceLatLonUnit/40.750095/-73.998867/25.737315/-80.309137/K

(Yes, this URL looks a little busy, but remember you would use INSERT FROM URL in FileMaker so it’s super easy.)

 

POSTMAN, TERMINAL, BROWSER, FILEMAKER, …., returns:

Just substituting “M”, for “K” as the last parameter, we get:

The cool thing about this service is that we can run it from anywhere if we choose.

 

(4) GET DATE INFO

 

Although there are many examples of where we have specific micro-service methods for dates including getting workdays with or without holidays, sometimes, it’s just helpful to get a screenful of information about a particular date. Is this year a leap year? What’s the day number in this year? People post questions like these often.

 

Now, depending on your needs, you might well write a micro-service method called “isLeapYear()” which returns true or false. (Or, you might “re-invent the wheel”, hopefully not, and write a custom function that determines what a ready-to-use date API can tell you.)

 

Having methods you call by name to get particular information is a good idea. But, for this last example, we will just return several pieces of data you might want to just look up for a given date. You would probably also have specific date methods you call as well.

 

In our micro-service, we created a method called “dateInfo”. Now, since this is a micro-service, we can all that method using any program that can issue HTTP verbs. In the display below, we URL-Encoded the date so the “/“ characters don’t cause problems in the micro-service.

 

Note: FileMaker’s GetAsUrlEncoded() function takes care of encoding the date so it looks as you see below in POSTMAN.

 

POSTMAN:

 

TERMINAL:

 

KEYBOARD MAESTRO:

Again, creating a super simple Keyboard Maestro macro c your service. With KeyBoard Maestro, you can do just about anything you want with that text (since we store it in a macro variable you could continue to work with).

 

(FileMaker, OTHERS….)

 

It’s important to note that even with the multiple-lines of date information returned, we used a RETURN-DELIMITED list for easy processing. Thus, if needed , you could still extract individual parts of the date information using, in FileMaker, GetValue().

 

 

(5) A GENERIC DATE AND TIMESTAMP CONVERTER

 

Since FileMaker’s date functions don’t let you easily convert between dates or timestamp formats, a simple micro-service method can make your life much easier from application to application. Featuring “configuration” over “coding”, you specify the format of what you want to do rather than coding it every single time you need to change a date or timestamp format.

 

In the example below, you enter:

 

1. Input Date Format Definition: The format of the date to convert using standard formatting characters.

 

2. Date Example to Convert: The date or timestamp format FileMaker (or any other GET-enabled application) doesn’t understand.

 

3. Desired Output Date Definition: The format for your converted date or timestamp.

 

Below, once you tab off the third field, FileMaker calls the service and gets your converted date.

 

Cool, right?

No custom functions or other hoops to (repeatedly) jump through necessary.

 

——

 

These services should work for any application that can issue HTTP verbs.

 

——

 

Hopefully, these more realistic examples are helpful for seeing how micro-services can be useful for your applications.

 

ODDS AND ENDS

 

Passing Parameters to the Service

 

From an application program, like FileMaker, you'd usually want to include parameters to the web service. Parameter processing is quite easy using SparkJava.

 

To include a parameter in FileMaker's INSERT FROM URL, you just append the field.

 

For example, from FileMaker, to pass a "firstName" field to the service you would do something like this for the INSERT FROM URL:

 

"localhost:4567/sayHello/" & firstName

 

---

 

Then, inside the web service, you have a slightly different signature to include the parameter. You also need to get that parameter using the method’s "request” object — see code snippet below.

 

Updated service signature to receive a parameter:

 

What About Special Characters In Parameters?

 

If your parameters have special characters (spaces, slashes, …) you may need to wrap them in a GetAsURLEncoded() FMP function (see below).

 

Often the extra GetAsURLEncoded() isn’t necessary; it just depends on the parameter you’re passing. With a FMP Timestamp string in the screenshot above, the “fromDate” has problem characters (slashes) between date parts. The GET service interprets those “/“ characters, if sent as literal “/“ characters, as separate delimiters for additional GET method parameters. Then, in the service, if what you pass doesn’t match an existing service “signature” (number of parameters, in this case), the service won’t find the right method to run. Thus, when you have slashes (or, in general, other problem characters) in parameter values, which can confuse the service, the GetAsUrlEncoded() encodes them so they’re not sent literally.

 

Secure Connections?

 

Using a single line of code, assuming you have the SSL configuration set up with a Java KeyStore, you can make your web service connections secure. Check the SparkJava site for more info.

 

Documentation

    Check the documentation for all the cool things you can do with the SparkFramework. And, if interested, check out the user group YouTube.com video in the RESOURCES section for a long demonstration of SparkJava features.

 

Other Frameworks?

 

SparkJava is a great framework for all types of micro-services and even prototyping services. It's quick and easy. It's fast. Many users have SparkJava sites serving over 10,000 users per day (per SparkJava’s 2005 survey on their site). For production use, many companies also use SpringBoot for their micro-service framework. SpringBoot leverages the immense and powerful Spring framework. Many developers use SparkJava for production work, too, but that’s a team decision you’d need to make at your company.

 

ADVANTAGES VS. DISADVANTAGES

 

Every technology has its pluses and minuses. Below is a table showing a few of both.

 

 

CONCLUSION

 

Micro-services add powerful REST capabilities to any application that can issue HTTP verbs (such as GET and POST). Micro-services are fast, fun, and, once setup, straightforward to use. If you see more advantages than disadvantages, Give micro-services a try.

 

RESOURCES

 

A user group video on Youtube.com demonstrating simple and more advanced examples of the framework is here (for more advanced needs):

 

https://www.youtube.com/watch?v=q7Gbdr75kiU

 

 

A video showing IntelliJ and maven on Youtube (among many) is here:

 

https://www.youtube.com/watch?v=pt3uB0sd5kY

1 person found this helpful

Attachments

    Outcomes