Search code examples
javajakarta-eequarkusjava-ee-8

How to implement a Rest endpoint along a Websocket endpoint


I want to expose an additional Rest endpoint along a Websocket endpoint.

The websocket endpoint is already implemented and works, but I have trouble hitting the Rest endpoint.

Any idea what I'm missing here? I expect to run localhost:8080/hello with a text plain result of hello.

Btw, I'm using Quarkus if that matters.

Here is my project structure

│   │   ├── java
│   │   │   └── org
│   │   │       └── company
│   │   │           ├── chat
│   │   │           │   ├── boundary
│   │   │           │   ├── control
│   │   │           │   └── entity
│   │   │           ├── JAXRSConfiguration.java // Rest endpoint ???
│   │   │           └── websockets
│   │   │               └── ChatSocket.java // Websocket server endpoint (works)
│   │   └── resources
│   │       ├── application.properties
│   │       ├── application.properties.example
│   │       └── META-INF
│   │           └── resources
│   │               ├── index.html

JAXRSConfiguration.java

package org.company;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;

@ApplicationPath("hello")
public class JAXRSConfiguration extends Application {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

ChatSocket.java

package org.company.websockets;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.time.LocalDateTime;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.company.chat.boundary.ChatResource;
import org.company.chat.entity.Chat;
import org.company.chat.entity.ChatGroup;
import org.company.chat.entity.ChatMessage;
import org.company.time.Time;
import org.jboss.logging.Logger;

@ServerEndpoint("/chat/websocket/{username}/{chatRoom}")
@ApplicationScoped
public class ChatSocket {

    @Inject
    Time time;

    @Inject
    ChatResource chatResource;

    // Chatroom, user, session dictionary
    final Dictionary<String, Map<String, Session>> chatRooms = new Hashtable<>();


    @OnOpen
    public void onOpen(final Session session, @PathParam("username") final String username, @PathParam("chatRoom") final String chatRoom) {
        // ...
    }

    @OnClose
    public void onClose(final Session session, @PathParam("username") final String username, @PathParam("chatRoom") final String chatRoom)
            throws Exception {
        // ...
    }

    @OnError
    public void onError(final Session session, @PathParam("username") final String username, @PathParam("chatRoom") final String chatRoom,
            final Throwable throwable) throws Exception {
        // ...
    }

    @OnMessage
    public void onMessage(String json, @PathParam("username") final String username, @PathParam("chatRoom") final String chatRoom)
            throws Exception {
        // ...        
    }

    private void broadcast(final String event, final String chatRoom) {
        // ...
    }

Solution

  • The solution was simply to add another @Path annotation.

    Here I changed JAXRSConfiguration.java as you can see in the following. Works now, if I call the localhost:8080/api/hello endpoint.

    @ApplicationPath("api") // Changed the basic route to 'api'
    @Path("hello") // Added a new path
    public class JAXRSConfiguration extends Application {
    
        @GET
        @Produces(MediaType.TEXT_PLAIN)
        public String hello() {
            return "hello";
        }
    }