All Projects → conskit → Conskit

conskit / Conskit

A Clojure Application Toolkit

Programming Languages

clojure
4091 projects
macros
77 projects

Projects that are alternatives of or similar to Conskit

Aspect4Delphi
Concepts of aspect-oriented programming (AOP) in Delphi.
Stars: ✭ 28 (+211.11%)
Mutual labels:  interceptor
Go Grpc Middleware
Golang gRPC Middlewares: interceptor chaining, auth, logging, retries and more.
Stars: ✭ 4,170 (+46233.33%)
Mutual labels:  interceptor
Testing Nestjs
A repository to show off to the community methods of testing NestJS including Unit Tests, Integration Tests, E2E Tests, pipes, filters, interceptors, GraphQL, Mongo, TypeORM, and more!
Stars: ✭ 685 (+7511.11%)
Mutual labels:  interceptor
Turbo
A lightweight microservice tool, turn your grpc|thrift APIs into HTTP APIs!
Stars: ✭ 275 (+2955.56%)
Mutual labels:  interceptor
Muuntaja
Clojure library for fast http api format negotiation, encoding and decoding.
Stars: ✭ 304 (+3277.78%)
Mutual labels:  interceptor
Uni Simple Router
a simple, lightweight routing plugin that supports interception and lifecycle triggering
Stars: ✭ 481 (+5244.44%)
Mutual labels:  interceptor
RetryRequestInterceptor-for-OkHttp
a interceptor for OkHttp which can save failed request in storage and will retry request until success or retry times over limit , or request live time over limit
Stars: ✭ 42 (+366.67%)
Mutual labels:  interceptor
Blockhook
Hook Objective-C blocks. A powerful AOP tool.
Stars: ✭ 742 (+8144.44%)
Mutual labels:  interceptor
Ng Http Loader
🍡 Smart angular HTTP interceptor - Intercepts automagically HTTP requests and shows a spinkit spinner / loader / progress bar
Stars: ✭ 327 (+3533.33%)
Mutual labels:  interceptor
Kakapo.js
🐦 Next generation mocking framework in Javascript
Stars: ✭ 535 (+5844.44%)
Mutual labels:  interceptor
Fetch Intercept
Interceptor library for the native fetch command inspired by angular http intercepts.
Stars: ✭ 279 (+3000%)
Mutual labels:  interceptor
Ok2curl
Convert OkHttp requests into curl logs.
Stars: ✭ 295 (+3177.78%)
Mutual labels:  interceptor
Xniffer
A swift network profiler built on top of URLSession.
Stars: ✭ 488 (+5322.22%)
Mutual labels:  interceptor
wxapp-api-interceptors
微信小程序api拦截器
Stars: ✭ 99 (+1000%)
Mutual labels:  interceptor
Viewpump
View Inflation you can intercept.
Stars: ✭ 736 (+8077.78%)
Mutual labels:  interceptor
DotNETCarRental
Daily car rental simulation with ASP.NET.
Stars: ✭ 13 (+44.44%)
Mutual labels:  interceptor
Angular Token
🔑 Token based authentication service for Angular with interceptor and multi-user support. Works best with devise token auth for Rails. Example:
Stars: ✭ 376 (+4077.78%)
Mutual labels:  interceptor
Vue Loadable
⏳ Improve your loading state control with pretty simple methods and helpers.
Stars: ✭ 23 (+155.56%)
Mutual labels:  interceptor
Router
一款单品、组件化、插件化全支持的Andoid端路由框架。
Stars: ✭ 741 (+8133.33%)
Mutual labels:  interceptor
Axios Auth Refresh
Library that helps you implement automatic refresh of authorization via axios interceptors. You can easily intercept the original request when it fails, refresh the authorization and continue with the original request, without user even noticing.
Stars: ✭ 502 (+5477.78%)
Mutual labels:  interceptor

Conskit Build Status Dependencies Status Clojars Project

Conskit (Construction Kit) is a toolkit for building Clojure web applications in a very modular and consistent manner while still providing freedom and flexibility that has become commonplace in the Clojure community.

Quick Links

Conskit at a Glance

Conskit was built using Trapperkeeper from puppetlabs, a microservices framework, as a base. In fact, at it's core Conskit is simply a single Trapperkeeper service that provides the following methods: register-bindings!, register-controllers! and register-intercepters!. Before diving any further into their purposes, I highly recommend taking a glance at Trapperkeeper's comprehensive documentation and in particular, how to define services.

Actions

The primary unit of work in Conskit is an Action. Actions are invokable objects that accepts a one parameter. Here is the simplest example of an Action defined using the action macro:

(ns com.foobar)

(def test-action
  (action
    do-all-the-things
    [data]
    "Hello World"))

Bindings

In Conskit, bindings are basically a map of domain resources and services that needs to be shared across actions globally. For example:

{:conn {:subprotocol "mysql"
        :subname "//127.0.0.1:3306/clojure_test"
        :user "clojure_test"
       :password "clojure_test"}
 :send-email! email-fn
 :encryptor #(encr %)
 :decryptor #(decr %)
 :send-to-s3! #(aws-put ...)}

Controllers

Controllers are logical groupings of Actions. They're also responsible for providing their Actions with access to bindings. Here's an example of a controller defined using the defcontroller macro:

(defcontroller test-controller
  [conn send-email! send-to-s3!] ;; Domain resources/services required
  test-action            ;; Action defined earlier
  (action                ;; Inline Action
    do-one-thing
    [data]
    "Goodbye Mars"))

Interceptors

You can think of interceptors as something analagous to ring middleware (or pedestal's interceptors) except that it is setup to be more declarative. Similar to ring middleware they allow you to effectively wrap actions to perform any additional functionality. Interceptors are defined using the macro definterceptor:

(definterceptor
  ^:logger
  log-things
  "I log everything"              ;; optional docstring
  [f config request]
  (log/info "Entering action")
  (let [result (f request)]
    (log/info "Leaving action")
    result))

This interceptor could then be declared on an action like this:

(def logged-action
  (action
    ^{:logger {:level :info}}
    do-foo-things
    [request]
    "Hello World"))

In our log-things interceptor, f is the function for the action being wrapped, config is the information provided when the interceptor was declared (in this case it would be {:level :info}) while request is simply the single argument to the action.

Registration

After all your actions, bindings, controllers and interceptors have been defined, how do they all tie together? This is where our Trapperkeeper service comes into play. You would effectively create your own Trapperkeeper servive that depends on the service provided by Conskit (:ActionRegistry) and then, using the methods provided by the service, you would register your controllers, bindings and interceptors:

(defservice my-service
  [[:ActionRegistry register-bindings! register-controllers! register-interceptors!]]
  (init [this context]
    (register-bindings! {:conn {:subprotocol "mysql"
                                :subname "//127.0.0.1:3306/clojure_test"
                                :user "clojure_test"
                               :password "clojure_test"}
                         :send-email! email-fn
                         :encryptor #(encr %)
                         :decryptor #(decr %)
                         :send-to-s3! #(aws-put ...)})
    (register-controllers! [test-controller])
    (register-interceptors! [log-things])
    context))

Add your service to your bootstrap.cfg along with Conskit's registry service:

conskit.core/registry
com.foobar/my-service

Then once Trapperkeeper boots up then Conskit will take care of the rest.

I thought you said Web applications...

You're correct. So far I haven't shown any mention of routing, templates, webserver, database abstractions etc. The idea here is that Conskit (Hint: Construction Kit) expects you to bring your own parts/batteries. These parts that you bring to the table are also going to be Trapperkeeper services. For example, lets say we wanted to use http-kit as our web server:

;; Wont really work
(defservice
  web-server-service WebServer
  [[:ConfigService get-in-config]]
  (start [this context]
    (let [handler (wrap (get-handler))
          options (get-in-config [:server])
          stopper (run-server handler (assoc options :queue-size 40000))]
      (log/info (str "Starting Web server on port " (:port options)))
      (assoc-in context [:server :stopper] stopper)))
  (stop [this context]
    (log/info "Stopping Web server.")
    (when-let [stopper (get-in context [:server :stopper])]
      (stopper :timeout 5000))
    (assoc-in context [:server :stopper] nil))
  (add-handler [this handler]
    (..)))

;;  Then back in our service

(defservice my-service
  [[:ActionRegistry register-bindings! register-controllers! register-interceptors!]
   [:WebServer add-handler]]         ;; Depend on WebServer service
  (init [this context]
    (register-bindings! {:conn {:subprotocol "mysql"
                                :subname "//127.0.0.1:3306/clojure_test"
                                :user "clojure_test"
                               :password "clojure_test"}
                         :send-email! email-fn
                         :encryptor #(encr %)
                         :decryptor #(decr %)
                         :send-to-s3! #(aws-put ...)})
    (register-controllers! [test-controller])
    (register-interceptors! [log-things])

    (add-handler some-ring-handler) ;; Call WebServer method
    context))

Add the webserver to our bootstrap.cfg and done!

conskit.core/registry
com.foobar/my-service
com.foobar/web-server-service

But! Of course it would be nice to have some reasonable defaults for these and other kinds of services:

What about the actions?

The Conskit registry service actually provides an additional method method called get-action that could be used to retrieve any action that was registered in a controller. get-action expects to be provided with a keyword with the action ID and it will return an ActionInstance on which conskit.protocols/invoke can be called.

The action IDs are created by concatenating the name provided with the namespace it was declared/defined in. So in our very first example of a simple action. Its ID would actually be :com.foobar/do-all-the-things:

(get-action :com.foobar/do-all-the-things)

So essentially your routing service could leverage get-action and dispatch actions based on the ID provided

Learn more about the Core Concepts here.

What makes conskit different?

The main selling point of this toolkit is that everything is replaceable including the core service provided. You have the option to use third-party services which may register their own actions, controllers, bindings and interceptors, you can be selective and use only a subset of the functionality offered by the third party or you can choose to roll your own. Conskit does not attempt to provide you with a "framework" but to provide you with the facility to construct your own "framework" (or application) from several reusable and replaceable parts.

Why you might decide against Conskit?

  • Perhaps you're not a fan of all the macros or Trapperkeeper
  • The declarative setup for interceptors makes the true nature of actions less obvious/implicit
  • more...?

Credits

Conskit and its various modules would not exist without the foundation provided by the following libraries and supporting articles.

Contributors

Conskit was created by Jason Murphy

License

Copyright © 2016 Jason Murphy

Distributed under the Apache License, Version 2.0.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].