GithubHelp home page GithubHelp logo

silky / dhallia Goto Github PK

View Code? Open in Web Editor NEW

This project forked from imalsogreg/dhallia

0.0 1.0 0.0 63 KB

Dhall-configured inductive API definitions

License: BSD 3-Clause "New" or "Revised" License

Dhall 4.73% Nix 7.23% Haskell 88.04%

dhallia's Introduction

Dhallia

An API Gateway configured in Dhall.

Dhallia lets you use Dhall types and expressions to wrap and compose underlying APIs. Run-time type information and the self-contained nature of Dhall expressions makes it easy to explore and distribute APIs

Stability & Features

Nowhere close to usable. This is just an experiment. The main point of the repository is to illustrate the inductive API concept and get feedback on it. Nice implementation could come later.

  • Composable REST APIs
  • Composable websocket APIs
  • Client REPL
  • Circuit breaking
  • Dry-run mode
  • Configurable caching
  • Configurable logging & metrics
  • Documentation
  • Admin UI
  • Authentication
  • Authorization
  • [ ]

Code organization

Core library: src

  • Logic for interpreting dhall API specifications
  • Typechecking API compositions
  • Core implementations of application logic

Inductive APIs

dhallia provides a format for modeling APIs in the dhall language and using them as an HTTP client. API definitions are "raw" or "composite"

Raw APIs (the base case)

We'll model an hypothetical API that creates short greetings for users. It accepts Requests like https://example.com/greet/<name> and returns responses like { "greeting", "Hello, Pete!" }.

let Req = ./Request.dhall

let ExampleInput  = { name :     Text }
let ExampleOutput = { greeting : Text }
in {
rawExample =
  { inputType  = ExampleInput,
    outputType = { greeting : Text },
    toRequest  = \(input : ExampleInput) ->
                   Req.addPathPart (input.name) Req.default
  }
}

The inputType and toRequest fields describe how we will generate requests from dhallia. The outputType field describes how to interpret the JSON response.

What makes an API "Raw" is the fact that we describe how to turn dhall values into an HTTP request.

Composite APIs (the inductive cases)

We can alternatively define an Fmap API in terms of some parent API and a function f that maps the parent's output to a new output.

let Req = ./Request.dhall

let ParentInput  = { name :     Text }
let ParentOutput = { greeting : Text }
let MyOutput     = { extended : Text }
in {
fmapExample =
  { parent     = "rawExample",
    outputType = MyOutput,
    f          = \(i : ParentOutput) ->
                   { extended = "${i.greeting}. How are you?" }
  }
}

And we can define an 'Ap' API in terms of two parent APIs and a combining function.

let Req = ./Request.dhall

in {
apExample =
  { parentA    = "rawExample",
    parentB    = "fmapExample",
    outputType = { compositeGreeting : Text },
    f          = \(a : { greeting : Text }) ->
                 \(b : { extended : Text }) ->
                   { compositeGreeting =
                     "We say to you, ${a.greeting} and ${b.extended}!"
                   }
  }
}

Runtime

Above we described our APIs, now we want to use them.

Right now the only way to use them is to parse the API definitions, then construct inputs as dhall values in Haskell, and call the runRequests function.

Why?

If you are on the receiving end of a microservice architecture, collecting data from from many sources and combining it correctly can be difficult.

The goal of inductive API definitions is to provide what appears to be a single HTTP API that provides responses directly useful to your domain, where you previously had to interact with many APIs that each provided a just piece of that larger domain.

In addition to calling a composite API, we may want other behavior to compose - caching logic for example, or the generation of swagger-like user interface, or collections of request-response pairs as test data fixtures.

Try it out

This requires nix.

test-server

In a dedicated terminal, run the test server. It's a small snap server that restarts on code change. This is the server that our sample Raw API will wrap.

./test-server.hs

HTTP client

Implementation and sample usage are currently mixed together in src/API.hs.

$ nix-shell
> cabal new-repl
*API> test

TODO: Obviously, improve the example case.

dhallia's People

Contributors

fintanh avatar imalsogreg avatar rebeccaskinner avatar srenatus avatar

Watchers

 avatar

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.