Popularity
3.1
Growing
Activity
0.0
Stable
12
2
0
Programming language: Crystal
Tags:
Framework Components
cr-melon alternatives and similar shards
Based on the "Framework Components" category.
Alternatively, view cr-melon alternatives based on common mentions on social networks and blogs.
-
shrine.cr
File Attachment toolkit for Crystal applications. Heavily inspired by Shrine for Ruby. -
Exception Page
An exceptional exception page for Crystal web libraries and frameworks -
praetorian
A minimalist Crystal authorization system inspired by https://github.com/varvet/pundit. -
motion.cr
Motion is a framework for building reactive, real-time frontend UI components in your Amber application using pure Crystal that are reusable, testable & encapsulated. -
kemal-auth-token
Kemal middleware to authentication via HTTP header token using JWT -
device_detector
Crystal shard for device detection by User-Agent string -
mochi
Mochi is a authentication shard inspired by devise. Mochi is designed for the Amber framework with support for both Granite & Jennifer ORM's. -
mime-types.cr
MIME Types for Crystal :: A port of the Ruby MIME::Types library -
Athena Event Dispatcher
A Mediator and Observer pattern event library -
request_id
Middleware for generates / pick up a unique request ID for Crystal servers. -
Athena Negotiation
Framework agnostic content negotiation library
Clean code begins in your IDE with SonarLint
Up your coding game and discover issues early. SonarLint is a free plugin that helps you find & fix bugs and security issues from the moment you start writing code. Install from your favorite IDE marketplace today.
Promo
www.sonarlint.org
Do you think we are missing an alternative of cr-melon or a related project?
README
Melon
Class based Http APIs in crystal
Description
This is a proof of concept of creating a shard that allows people to create APIs with classes with the following fetaures:
- DSL for building the APIs (get, put, post, etc...)
- Inherit form an other APIs
- Mounting other APIs at an endpoint
- Inspectable routes and APIs for documentation
[Example](examples/simple.cr):
require "../src/melon"
USERS = [
{name: "John Doe"},
{name: "Someone Else"},
]
class Users < Melon::Api
description "Users Endpoint"
get description: "Get all users" do
json USERS
end
end
class Root < Melon::Api
description "My Awesome API"
get description: "Simple GET request." do
ok "text/plain", "Hello there!"
end
post do
ok "text/plain", "You have posted something."
end
mount Users, "users"
end
Melon.print_routes Root
Melon.listen Root, 8080
# Root - My Awesome API
# ----------------------------------------
# โโ GET - / # Simple GET request.
# โโ POST - /
# โโโฌโ API - /users # Users Endpoint
# โโ GET - / # Get all users
# ----------------------------------------
# Listening on http://0.0.0.0:8080
Explanation
This implementation is heavily uses macros and a pattern matching to make it work:
- macros create a subclass
class Route%id < Route # Route__temp_25
- macros create overloaded methods with the subclass
def handle_route(id : Route__temp_25)
- macros save the instances of these classes in a registry for access with
metadata
Registry[path] = Route%id.new "some metadata"
- overloaded methods are run with the subclass from the matching route
in the registry
instance.handle_route(Registry[path])
- a fallback implemention is needed for matching the base class
def handle_route(id : Route)
for compability (to actually compile) which will never be called - all created routes are inspectable in the registry
This behavior used can further explained with the following code:
# Define a class
class A
end
# Define a registry
REGISTRY = {} of String => A
# Define the which will have the DSL
class B
# Define the DSL method
macro make_print(key, text)
# Create a sub class with a unique name
class A%name < A
end
# Save an instance of that class in the registry
REGISTRY[{{key}}] = A%name.new
# Create an overloaded method that responds to that class only
def handle_print(id : A%name)
# Run things here
puts {{text}}
end
end
# Create a fallback method for compability
def handle_print(id : A)
puts "fallback"
end
# Have a method call the overloaded functions
def print(key)
handle_print REGISTRY[key]
end
# Actually make the overloaded methods
make_print "a", "hello"
make_print "b", "bye"
end
b = B.new
b.print "a" # "hello"
b.print "b" # "bye"