magicbane alternatives and similar packages
Based on the "Web" category.
Alternatively, view magicbane alternatives based on common mentions on social networks and blogs.
-
haskell-bitmex-rest
swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition. -
servant
Main repository for the servant libraries — DSL for describing, serving, querying, mocking, documenting web applications and more! -
swagger-petstore
swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition. -
neuron
Future-proof note-taking and publishing based on Zettelkasten (superseded by Emanote: https://github.com/srid/emanote) -
tagsoup
Haskell library for parsing and extracting information from (possibly malformed) HTML/XML documents -
keera-hails-reactive-htmldom
Keera Hails: Haskell on Rails - Reactive Programming Framework for Interactive Haskell applications -
ghcjs-dom
Make Document Object Model (DOM) apps that run in any browser and natively using WebKitGtk
WorkOS - The modern identity platform for B2B SaaS
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of magicbane or a related project?
README
An object appears at your feet! The voice of Anhur rings out: "Use my gift wisely!" a - an athame named Magicbane.
magicbane
Magicbane is a Haskell framework for developing ops-friendly, high-performance, RESTful web services.
Okay, that's Dropwizard's tagline.
But just like Dropwizard in the Java world, Magicbane combines the best available Haskell libraries to provide a complete web development experience that reduces bikeshedding, wheel reinvention and the number of import
lines. Hopefully :)
In particular, Magicbane combines the following libraries:
- RIO for the Prelude.
- Servant for REST. It lets you describe web APIs with expressive type system features and implement request handlers with simple functions. Actually somewhat similar to JAX-RS/Jersey, but instead of annotations we have types, because it's Haskell instead of Java. The main feature of Magicbane is an easy way to add stuff (okay, let's call it "modules") on top of Servant.
- Warp for HTTP.
- Aeson for JSON.
- data-has for extending the app context with services (modules). That thing remotely resembles dependency injection. But it's really cool!
- envy for configuration. Store config in environment variables!
- fast-logger for logging. Integrated into RIO's logging API, and
monad-logger
as well for libraries that use it. - EKG+monad-metrics for metrics.
monad-metrics
lets you easily measure things in your application: just uselabel
/counter
/distribution
/gauge
/timed
in your handlers. The EKG ecosystem has backends for InfluxDB, Carbon (Graphite), statsd, Prometheus and others… And a simple local web server for development. - refined for validation. Why use functions for input validation when you can use types? Magicbane integrates
refined
with Aeson, so you can write things likecount ∷ Refined Positive Int
in your data type definitions and inputs that don't satisfy the constraints will be rejected when input is processed. - http-client(-tls) for, well, making HTTP requests. Most high level HTTP client libraries are built on top of that. Magicbane provides a small composable interface based on http-conduit, which lets you e.g. stream the response body directly into an HTML parser.
- http-link-header for the HTTP
Link
header, unsurprisingly. - unliftio for uhhh unlifting.
- wai-cli for starting Warp. Why write the same stuff in the
main
function for every new app when you can just use this one. It supports stuff people usually forget to implement there, like UNIX domain sockets, socket activation and graceful shutdown.
Not part of Magicbane, but recommended:
- rapid for fast development with GHCi hot reload.
- hasql for talking to PostgreSQL.
- html-conduit for parsing HTML.
- microformats2-parser for parsing microformats2 from that HTML.
- pcre-heavy for regular expressions.
Magicbane was extracted from Sweetroll.
Usage
Here's a hello world service. Just a simple file you can launch with stack script! (Don't use stack script in production though, use proper stack builds, with optimizations and the threaded runtime.)
#!/usr/bin/env stack
{- stack runghc --package magicbane -}
{-# LANGUAGE NoImplicitPrelude, OverloadedStrings, UnicodeSyntax, DataKinds, TypeOperators #-}
import RIO
import Magicbane
type HelloRoute = "hello" :> QueryParam "to" Text :> Get '[PlainText] Text
type ExampleAPI = HelloRoute
exampleAPI = Proxy ∷ Proxy ExampleAPI
hello ∷ Maybe Text → BasicApp Text
hello x = do
let x' = fromMaybe "anonymous" x
logInfo $ "Saying hello to " <> display x'
return $ "Hello " <> x' <> "!"
main = do
ctx ← newBasicContext
defWaiMain $ magicbaneApp exampleAPI EmptyContext ctx hello
This defines an API that consists of just one endpoint, /hello?to=someone
, that does exactly what it says on the tin.
Looks like a normal Servant app, but the handler is defined as a BasicApp
action. What's that?
That's just an example context for simple apps:
type BasicContext = (ModHttpClient, ModLogger)
type BasicApp α = RIO BasicContext α
Why isn't there Handler
/ ExceptT
mentioned anywhere?
Well, it's an antipattern that is now incompatible with http-conduit (needs MonadUnliftIO
) and monad-metrics (needs MonadMask
).
So Magicbane got rid of Servant's ExceptT usage.
To return a servantErr
, just throwM
(throwIO
) it.
Anyway, let's make our own context instead of using the basic one:
#!/usr/bin/env stack
{- stack runghc --package magicbane -}
{-# LANGUAGE NoImplicitPrelude, OverloadedStrings, UnicodeSyntax, DataKinds, TypeOperators #-}
import RIO
import Magicbane
type MyAppContext = (ModLogger, ModMetrics)
type MyApp = RIO MyAppContext
type HelloRoute = "hello" :> QueryParam "to" Text :> Get '[PlainText] Text
type ExampleAPI = HelloRoute
exampleAPI = Proxy ∷ Proxy ExampleAPI
hello ∷ Maybe Text → MyApp Text
hello x = timed "hello" $ do
let x' = fromMaybe "anonymous" x
logInfo $ "Saying hello to " <> display x'
return $ "Hello " <> x' <> "!"
main = do
(_, modLogg) ← newLogger (LogStderr defaultBufSize) simpleFormatter
metrStore ← serverMetricStore <$> forkMetricsServer "0.0.0.0" 8800
modMetr ← newMetricsWith metrStore
let ctx = (modLogg, modMetr)
defWaiMain $ magicbaneApp exampleAPI EmptyContext ctx hello
Now we have metrics and logging instead of HTTP client and logging!
timed
is used here to measure how long it takes to say hello.
See the examples
directory for more examples.
Development
Use stack to build.
$ stack build
And to run the examples:
$ stack exec runghc examples/larger.hs
Contributing
Please feel free to submit pull requests!
By participating in this project you agree to follow the Contributor Code of Conduct.
License
This is free and unencumbered software released into the public domain.
For more information, please refer to the UNLICENSE
file or unlicense.org.
(However, the dependencies are not all unlicense'd!)
*Note that all licence references and agreements mentioned in the magicbane README section above
are relevant to that project's source code only.