Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP POST example (REST) #616

Open
gadieichhorn opened this issue May 8, 2019 · 4 comments
Open

HTTP POST example (REST) #616

gadieichhorn opened this issue May 8, 2019 · 4 comments

Comments

@gadieichhorn
Copy link

Hi all,

I am after a working HTTP POST example. I can get the TCP example to send data to server but all the HTTP examples are too simplified. Is the POST not working? Anything I tried will lead to an empty content sent to the server.

I saw you have a Router in the pipeline, when will that be released? My plan is to build a simple REST server so POST, PUT, GET, ... is desired examples.

Thanks.

@jamesgorman2
Copy link
Collaborator

I extended the pk11 router for 0.5 here https://github.com/Trunkplatform/rxnetty-router We used this extensively. I'll work up a post example for you shortly/

@gadieichhorn
Copy link
Author

Thanks a lot! appreciated.

@jamesgorman2
Copy link
Collaborator

Here's the example (with some gradle stuff at the bottom). It's also worth checking through the issues for more info on releasing ByteBufs. Memory leaks are one of the biggest problems people have when receiving data.

import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.reactivex.netty.protocol.http.client.HttpClient;
import io.reactivex.netty.protocol.http.server.HttpServer;
import io.reactivex.netty.protocol.http.server.HttpServerRequest;
import io.reactivex.netty.protocol.http.server.HttpServerResponse;
import io.reactivex.netty.util.CollectBytes;
import org.pk11.rxnetty.router.Router;
import rx.Observable;

import java.nio.charset.Charset;

import static org.pk11.rxnetty.router.Dispatch.using;

public class PostExample {

  public static void main(String[] args) {

    HttpServer<ByteBuf, ByteBuf> server = HttpServer.newServer()
      .start(
        using(
          new Router<ByteBuf, ByteBuf>()
            .POST(
              "/echo",
              new EchoHandler()
            )
            .notFound(new Handler404())
        )
      );

    HttpClient.newClient("localhost", server.getServerPort())
      .createPost("/echo")
      .writeStringContent(
        Observable.range(1, 10).map(i -> "This is test " + i + "\n"),
        s -> true // flush on each selector, see below
      )
      .flatMap(
        response ->
          response.getContent().compose(CollectBytes.all())
            .map(
              b -> {
                String s = b.toString(Charset.defaultCharset());
                b.release();
                return s;
              }
            )
      )
      .subscribe(
        System.out::println,
        System.err::println
      );

    server.awaitShutdown();
  }

  private static class EchoHandler implements io.reactivex.netty.protocol.http.server.RequestHandler<ByteBuf, ByteBuf> {

    @Override
    public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) {
      // Three notes here:
      // 1) we have to release the content manually. Where you only need to know
      //    about the completion of processing, you can also use autoRelease()
      // 2) flushing is also manual - we are using a naive flush algorithm to
      //    prevent the response blocking once the write buffer is full.
      // 3) it is not guaranteed the ByteBuf block boundaries are the same as those sent
      return response.writeStringAndFlushOnEach(
        request.getContent()
          .map(
            b -> {
              String s = b.toString(Charset.defaultCharset());
              b.release();
              return s;
            }
          )
      );
    }
  }

  private static class Handler404 implements io.reactivex.netty.protocol.http.server.RequestHandler<ByteBuf, ByteBuf> {
    @Override
    public Observable<Void> handle(HttpServerRequest<ByteBuf> request, HttpServerResponse<ByteBuf> response) {
      System.out.println("Not found: " + request.getUri());
      return response.setStatus(HttpResponseStatus.NOT_FOUND)
        .writeString(Observable.just("Not found"));
    }
  }
}

Gradle requires manually setting a repo to get the router code

plugins {
    id 'java'
}

group 'io.reactivex.netty'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
    maven {
        url 'https://dl.bintray.com/trunkplatform/trunk-java-oss'
    }
}

dependencies {
    implementation 'io.reactivex:rxnetty-http:0.5.3'
    compile 'org.pk11.rxnetty:rxnetty-router-core:1.4.2'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

@gadieichhorn
Copy link
Author

Thanks, @jamesgorman2 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants