What are webhooks

WebHooks

What are WebHooks?

  • WebHooks are event callbacks over http. 
  • The server or app calls your URL.
  • It’s not a protocol, there is no standard. Its just a design pattern.
  • When something happens, perform HTTP POST with relevant data to a URL that the user gives you.

Modern API and WebHooks

Before we see how webhooks work, lets look at how HTTP works?

Diagram displaying How HTTP works.

Unfortunately that’s how the web is today.

  • We can talk to web apps, but they really can’t talk to us.
  • Its as if you had a telephone system where you could only make calls, but never receive them. 
  • 98.5% of polls are wasted.
Flow of Modern API

So to get the updated information you may need to refresh the page by yourself. Which is unacceptable!!!! And if it takes too much time to refresh the site User may leave the site. So refresh button is an EVIL and we need to stop using it.

It’s not that they can’t talk to the caller, they just don’t. We need to start placing event hooks in them. So we should have event driven programming.

Flows of Modern API WebHooks

How does WebHook work?

Diagram showing how webhooks work.

Many modern applications/sites provide WebHooks for their end users. Like GitHub, Facebook etc. How to create our own webhook? Lets do it in a few moments.

Bore moving to code level implementations, lets look at pros and cons, known issues and check lists of implementing webhooks.

Thumbs-upThumbs-down
– Real time updates (almost).
– Without dedicated resources.
– Easily consumed.
– Easily Integrated.
– Poor user experience. You need to register and handle the callback.
– Debugging. Though now a days there are some way of doing it.

There are also many other benefits of using Webhooks along with some tips on how to use them.

 Known issues

ConsumerAPI Provider
DDoS attackMissed notification. Consumer may not get some result.Deduplication. Consumer may get same result multiple times.DDoS attack                                                               

A Distributed Denial of Service (DDoS) attack is an attempt to make an online service unavailable by overwhelming it with traffic from multiple sources. They target a wide variety of important resources, from banks to news websites, and present a major challenge to making sure people can publish and access important information.

Check lists

Keeping known issues in mind we can follow some checklists both on consumer and provider side to reduce the problems.

ConsumerAPI Provider
One callback per webhookTry to use human unreadable callback URLs.Expected answer? (Like Status 200)Handle request number.Monitor payload size.Implement authentication

Okay!! Lets do some coding now. 

Steps:

  1. Create a Dynamic Web Project. In Eclipse Go File>New>Other and choose “Dynamic Web Project” under Web.
  2. Add files shown in the following image. Content of each of the file will be discussed later.
Screenshot of Webhooks project structure.

MessageWebSocketSever.java

package com.ixora.webhooks;
 
import java.util.LinkedHashSet;
import java.util.Set;
 
import javax.enterprise.context.ApplicationScoped;
import javax.json.JsonObject;
import javax.json.spi.JsonProvider;
import javax.websocket.OnClose;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
 
 
@ApplicationScoped
@ServerEndpoint("/actions")
public class MessageWebSocketServer {
 
    private static final Set<Session> sessions = new LinkedHashSet<Session>();
 
    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
    }
 
    @OnClose
    public void onClose(Session session) {
        sessions.remove(session);
    }
 
    private static JsonObject createJsonMessage(String message) {
        return JsonProvider.provider().createObjectBuilder().add("jsonMessage", message).build();
    }
 
    public static void sendAll(String text) {
        synchronized (sessions) {
            String message = createJsonMessage(text).toString();
 
            for (Session session : sessions) {
                if (session.isOpen()) {
                    session.getAsyncRemote().sendText(message);
                }
            }
        }
    }
}
Code language: JavaScript (javascript)

TestServlet.java

package com.ixora.webhooks;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * Servlet implementation class TestServlet
 */
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
     
        
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
     
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {       
        MessageWebSocketServer.sendAll(request.toString());         
    }
     
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {      
        StringBuilder builder = new StringBuilder();
        String aux = "";
 
        while ((aux = request.getReader().readLine()) != null) {
            builder.append(aux);
        }
 
        String text = builder.toString();
        MessageWebSocketServer.sendAll(text);       
    }
}Code language: JavaScript (javascript)

index.html

<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script src="/websocket.js"></script> <link rel="stylesheet" type="text/css" href="/style.css"> </head> <body> <div id="wrapper"> <h1>Java WebHook Home</h1> <p>Welcome to the Java WebHook Home</p> <br /> <br /> <h3>WebHook Messages:</h3> <div id="content"> </div> </div> </body> </html>Code language: HTML, XML (xml)

style.css

body {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 80%;
    background-color: #1f1f1f;
}
 
#wrapper {
    width: 960px;
    margin: auto;
    text-align: left;
    color: #d9d9d9;
}
 
p {
    text-align: left;
}
 
#content {
    margin: auto;
    width: 960px;
}
 
.message {
    text-align: center;
    font-weight: bold;
    margin-bottom: 12px;
}Code language: CSS (css)

websocket.js

var socket = new WebSocket("ws://localhost:8080/WebSocket/actions");
socket.onmessage = onMessage;
 
 
function onMessage(event) {
    var message = JSON.parse(event.data);    
     printDeviceElement(message);   
}
 
 
function printDeviceElement(message) {
    var content = document.getElementById("content");  
     
    var deviceName = document.createElement("span");
    deviceName.setAttribute("class", "message");
    deviceName.innerHTML = message.jsonMessage;
    content.appendChild(deviceName);
}Code language: JavaScript (javascript)

So we are done with coding. 

Now run the application into the web server (Glass Fish for this case) and you will see the following screen

Screenshot of Webhooks output 1.

 Now type “http://localhost:8080/WebHooks/TestServlet” in a separate browser and you will get the following screen. We just printed the request as a text.

Screenshot of Webhooks output 2.

Add a Comment

Your email address will not be published. Required fields are marked *