#### Building a Web Service

NeXtMidas makes it very easy to create a web service that responds to HTTP (Hyper Text Transfer Protocol) requests. This section will demonstrate the steps to create your own web service.

NOTE: This section assumes the user is familiar with HTTP and knows some basics about HTTP messages.

There are two key parts to the web server:

1. The primitive to start/manage the server (this is the myserver class in the examples below).
2. The library to act as the server (this is the MyServer class in the examples below).

The primitive used to start/manage the server is usually very simple. It provides the interface between the server and the NeXtMidas environment that is running the server.

    package nxm.opt.prim; // <-- Your option tree goes in here

    import nxm.sys.lib.*;
    import nxm.opt.lib.*; // <-- Your option tree goes in here

    public class myserver extends Primitive {
      private MyServer server; // Handle to the server

      public int open() {
        int   port    = 9999; // <-- Get port number from command line
        Table options = null; // <-- Get options table from command line

        server = MyServer.startNewServer(M, this, port, options);

        return NORMAL;
      }

      public int process() {
        int status = NORMAL;

        if (!server.isRunning()) {
          status = FINISH;
        } else {
          // The server is running in its own thread, so this thread
          // needs to pause to prevent it from taking up too much CPU.
          Time.sleep(1.0);
        }

        return status;
      }

      public int close() {
        return NORMAL;
      }
    }

The library that extends `HSource` is where the real work gets done. The `start()` method starts the service, opens the socket, and starts the thread that will wait for incoming connections. The `handleRequest(String,HPage)` method will be called with each incoming request. The `handleRequest(String,HPage)` method is the one that does all of the real work. In this example `handleRequest` calls `processRequest` which does the work of writing out to the `HPage` (for any Java experts, the `HPage` class just wraps the underlying socket with a few ease-of-use methods).

    package nxm.opt.lib; // <-- Your option tree goes in here

    import nxm.sys.inc.*;
    import nxm.sys.lib.*;
    import nxm.sys.net.*;

    public class MyServer extends HSource {
      /** Title of server displayed on the top-level page. */
      private static final String SERVER_TITLE = "My server";
      /** Directory this service resides in. */
      private static final String SERVER_DIR   = "myserver";

      private HServer hserver; // Handle to the HServer in use.
      private Midas   midas;   // Handle to the current Midas context.
      private Command command; // The command that started the server.
      private Table   options; // Command options.
      private boolean running; // Is the server running?

      /** Creates a new instance of the server, but does not start it.
          @param midas The Midas context to use.
          @param cmd   The command running this server.
       */
      private MyServer(HServer hserver, Midas midas,
                       Command cmd, Table options) {
        super(SERVER_DIR);
        this.hserver = hserver;
        this.midas   = midas;
        this.command = cmd;
        this.options = options;
        this.running = true;
      }

      /** Tells if the server is running. */
      public boolean isRunning() {
        return running;
      }

      /** Starts the server.
          @param midas   The Midas context to use.
          @param cmd     The command running this server.
          @param port    The port to use.
          @param options Any options for the server.
          @return The server that has been started.
       */
      public static MyServer startNewServer(Midas midas, Command cmd,
                                            int port, Table options) {
        HServer  server   = HServer.launch(SERVER_TITLE, port);
        MyServer myserver = new MyServer(server, midas, cmd, options);

        server.addSource(myserver); // Connects the server
        midas.info("MyServer: Server has been started");

        return myserver;
      }

      public void handleRequest(String uri, HPage hp) {
        midas.info("MyServer: Got request for "+uri+" from "
                  +hp.getSocket().getRemoteSocketAddress());

        try {
          Table params = getParameters(uri); // Gets any URL parameters

          processRequest(hp, params);

        } catch(Exception e) {
          midas.warning("MyServer: Error while processing request "
                       +"for "+uri+": "+e);
          midas.printStackTrace(e);
        }
      }

      /** Processes the request.
          @param hp     The HPage to write to.
          @param params Any parameters from the HTTP request.
       */
      private void processRequest(HPage hp, Table params) {
        String name = params.getS("NAME");

        hp.open();
        hp.writeln("<html><body>");
        if (name == null) {
          hp.writeln("<h2>Hello World!</h2>");
        } else {
          hp.writeln("<h2>Hello "+name+"</h2>");
        }
        hp.writeln("</body></html>");
        hp.close();
      }
    }

This example can then be tested by using the following URLs in a web browser:

    http://localhost:9999/myserver
    http://localhost:9999/myserver?NAME=Agent+Smith

Note that there is no mechanism for stopping the server in this example. It will be necessary to use Ctrl+C to kill NeXtMidas in order to stop it. This example simply omits the mechanism for stopping the server since such is usually application dependant.

While this example is a simple one it can be easilly expanded to include more complex tasks that involve processing data and returning different types of data or images. Please see the `HPage` documentation for more information.