package sihl
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=38d5abd1d80aa4772c742a8bd4024afd39e23e2e02304b1cacfddde7dba2f43b
sha512=28f3236a51a501247a12f38441aab70e100936eca94a34d43a5734d1861021ac15dfa5457f87d9d0f87bc1f2fef9cda6d6fa6d11486797dd1b466d6bd85650ce
doc/index.html
Sihl
Sihl is a framework for building applications with OCaml and Reason.
Check out the tutorial to get started.
Overview
Following section outlines the design goals, features and main ingredients of Sihl.
Design goals
Following five design goals guide Sihl's development.
Developer happiness
The overarching goal is to maximize developer happiness. We think it is crucial to like the tools that we use.
Sustainable speed of development
This goal is about minimizing the gap between early speed of development and long-term maintanability. Combine functional programming, strict static typing and a modular architecture to quickly build systems that you are not afraid to touch. Thanks to the fast compiler, incremental build time is measured in milliseconds. Run your tests often and quickly. Omit type declarations while prototyping and let the compiler infer the types for you. Once the APIs settle, the compiler infers interfaces.
Composability
Apart from a tiny core that deals with dependency injection, everything is built using services and plain functions, even built-in in features. Compose your apps by picking functionality, one by one.
Minimization of magic
Many frameworks rely on complex macros at compile-time or reflection at runtime to offer ergonomic APIs. Sihl tries to minimize this sort of magic by making things explicit.
Sane defaults, powerful customizations
Sihl provides consistent and sane defaults while allowing for customizations. Get started with your project and fine-tune your BCrypt rounds and database connection pool sizes later.
Features
Here is a list of some of topics that Sihl is concerned with:
- Data: Connection pooling, migrations, database interaction
- Authentication: JWT, session management, token management
- Web: HTTP, middlewares, cookies, routes, templates, flash messages, JSON API
- Testing: Unit Tests, service tests, End-to-End tests, seeding, Fixtures
- Custom command line commands
- Pagination, sorting & filtering
- Logging
- Email scheduling, bulk email sending
- User management
- Authorization
- Job Queue
- Scheduler
- Block Storage
- Caching
- PDF, XLSX & CSV Export
- Secrets management
- Admin UI
The main ingredients
The "framework" is not only the code in the GitHub repo, but also documenation, concepts and architecture. Sihl consists of four parts.
Set of libraries
The OCaml ecosystem has many wonderful libraries that are often wrappers around battle tested C libraries. Sihl provides a consistent API on top with sane defaults for web development. Examples are: base64 encoded random byte generation, JWT encoding/decoding, BCrypt hashing, UUID generation.
Documenation & Best Practices
This document describes an architecture following principles of Domain-Driven Design. You are free to use any other architecture and to pick the parts of Sihl that you need.
Interfaces and default implementations
Everything is built using services, even built-in functionality. Sihl provides a set of service interfaces and default implementations for common tasks in web development like email sending, job queues, block storage and migrations. Implementing those interfaces is one of the main ways to extend Sihl.
Tiny core
To be 100% honest, there is a tiny core that deals with service dependency injection and life cycle management. But that's it, everything else is using that mechanism to provide its functionality! // TODO link to source of tiny core as a proof
Installation
opam
Install opam according to this.
Sihl has not been released to OPAM yet, we plan to release it in the coming days.
Run opaminstallsihl
.
TODO Provide starter skeleton as git repo
esy
TODO
nix
TODO
Tutorial
TODO
1. Your first Sihl app
- introduce folder structure
- separating http/cli from actual application
2. Your first Test
3. Your first Use Case
- create test for use case
- create use case, use first
- authz
- in memory repo
4. Your first JSON API
5. Your first Website
- add web stuff: site and json endpoint
5. Your first CLI Command
- add cli interface
6. Your first Migration
- implement postgresql repo
7. Launch your app ๐
- production settings
- build dockerfile
Concepts
On order to navigate the code base of provided Sihl modules and to make most of this documentation, there are some concepts that you need to familiarize yourself with.
Option, Result and Lwt
Make sure you understand conceptually Option
, Result
and Lwt. You should also familiarize yourself with the basic API of those modules.
Option
TODO vs. null/absence of something
Result
TODO no exceptions, just result
Lwt
Sihl uses Lwt to do non-blocking I/O. Because we assume that any I/O might fail, almost every API has nested Result.t
inside Lwt.t
like so ('a, 'e) Result.t Lwt.t
. This is in fact so common that Lwt provides a helper module Lwt_result.t
to ergonomically handle the nested Result.t
.
Since OCaml 4.08.1, the language has built in support for let*
syntax. This is similar to async/await in other languages like JavaScript. Sihl makes extensive use of this new syntax to flatten Lwt chains. This is a good primer.
This allows us to express domain logic without obfuscating it with noise that is caused by asynchronous operations.
Common patterns
TODO show common patterns:
- Result.of_option(~error)
- Lwt_result.map_err(...)
Architecture
TODO show file system