Giter VIP home page Giter VIP logo

jfry's Introduction

JFry Build Status

Java Fry is a web library inspired by Sinatra

Getting started

This will improve with time. You just create a new instance with a server adapter and a port number.

Then you can use JFry's DSL to register new Routes with their Handlers:

JFry.of(new JettyAdapter(), 8080)
  .options("/foo", req -> req.buildResponse().ok("bar"))
  .get("/foo", req -> req.buildResponse().ok("bar"))
  .head("/foo", req -> req.buildResponse().ok("bar"))
  .post("/foo", req -> req.buildResponse().ok("bar"))
  .put("/foo", req -> req.buildResponse().ok("bar"))
  .delete("/foo", req -> req.buildResponse().ok("bar"))
  .trace("/foo", req -> req.buildResponse().ok("bar"))
  .connect("/foo", req -> req.buildResponse().ok("bar"))
  .start();

Now you can browse to http://localhost:8080/foo

Why is JFry different?

JFry is strongly based on concepts related to Functional Programming: immutable objects, first-class functions, etc.

Probably the main difference between JFry and almost any other Java web library is that Route Handlers are defined as Request -> Response functions. This is a key design decision in order to benefit from functions' composition and decoration capabilities.

JFry doesn't make any assumption on the kind of use that you're going to give it. Therefore, the core artifact doesn't provide any templating engine, authentication method, json transformer, nothing, nada. Instead, it gives you an easy way to implement your own decorators to handle template rendering, input/output deserialization/serialization, authentication, session handling, etc.

Decorators and function chains

A function decorator is a function that extends the functionality of other compatible functions. JFry defines for your convenience some Functional Interfaces to make easier for you the creation of decorators Requests and Responses.

If you are using a simple Request -> Response Handler like so:

jfry.get("/doge", request -> request.buildResponse.ok("wow"))

And you need to allow access only to authenticated users, you could do something like:

// Providing that you have some authentication object like this one:

class Authenticator {
  public Handler authenticate(Handler handler) {
    return request -> {
      return request.mapHeader("X-Auth-Token", JWT::validate).orElse(false) 
               ? handler.apply(request) 
               : request.buildResponse().unathorized();
    }
  }
}

// Then you can do:

jfry.get("/doge", authenticator.authenticate(request -> request.buildResponse.ok("wow"))));

This mode of operation is based on a decorator that returns a new function that complies with a Handler Functional Interface and can be used as a Handler itself. This way, your initial Handler doesn't have to know anything about authentication and can be "clean" of dependencies and lines of code that don't have anything to do with your real business logic.

Sometimes, it's enough to manipulate the Request or the Response method. This is very useful when you need to deal with json content. Let's say that you need to receive a json object from your ursers and then return some other json to them. You could do:

// Providing that you have some json serialization/deserialization engine like this:

class JsonEngine {
  public RequestDecorator deserialize() {
    return request -> request.mapBody(Json::deserialize)
                             .map(request::withBody)
                             .orElse(request);
  }
  
  public ResponseDecorator serialize() {
    return response -> response.mapBody(Json::serialize)
                               .map(response::withBody)
                               .orElse(response);
  }
}

// Then you can do:

jfry.get("/doge", json.deserialize()
                      .andThen(request -> request.buildResponse.ok(request.<Doge>getBody()))
                      .andThen(json.serialize()));

RequestDecorator and ResponseDecorator are Functiontal Interfaces declared in org.jfry.decorators package.

In this case, we're taking advantage of the implicit type casts that occur inside Request and Response objects when you call to mapBody() or getBody(). You need to remember that this operations are unsafe. JFry will always think that you know what you're doing :)

Use the tests

You can learn a lot about JFry browsing through its tests

jfry's People

Watchers

 avatar

Forkers

borud solo1edu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.