All Projects → jeffgrunewald → maverick

jeffgrunewald / maverick

Licence: Apache-2.0 license
Web API framework with a need for speed

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to maverick

Vaxic
Node HTTP server framework
Stars: ✭ 45 (+221.43%)
Mutual labels:  web-framework, api-server
endpoints
Lightweight REST api backend framework that automatically maps urls to python modules and classes
Stars: ✭ 30 (+114.29%)
Mutual labels:  web-framework, api-server
Proteus
Lean, mean, and incredibly fast JVM framework for web and microservice development.
Stars: ✭ 178 (+1171.43%)
Mutual labels:  web-framework, api-server
Phoenix
Peace of mind from prototype to production
Stars: ✭ 17,476 (+124728.57%)
Mutual labels:  web-framework, api-server
nova
Web framework for Erlang.
Stars: ✭ 175 (+1150%)
Mutual labels:  web-framework, api-server
Webgo
A minimal framework to build web apps; with handler chaining, middleware support; and most of all standard library compliant HTTP handlers(i.e. http.HandlerFunc).
Stars: ✭ 165 (+1078.57%)
Mutual labels:  web-framework, api-server
Sanic
Async Python 3.7+ web server/framework | Build fast. Run fast.
Stars: ✭ 15,660 (+111757.14%)
Mutual labels:  web-framework, api-server
ExpressWebJs
ExpressWebJs is a Node FrameWork with expressive and organised syntax that runs on all major operating systems. It provides the starting point for creating your node project, allowing you to focus more on developing your amazing solution. It takes the pain out of development by easing common tasks (Environment Setup, Code Structure, Robust routi…
Stars: ✭ 58 (+314.29%)
Mutual labels:  api-server
framework
Cygnite PHP Framework- A Modern Toolkit For Web Developers
Stars: ✭ 43 (+207.14%)
Mutual labels:  web-framework
microAuth
A fast, documented, and tested python3 API boilerplate
Stars: ✭ 24 (+71.43%)
Mutual labels:  api-server
ncms
Java CMS engine. Host and develop multiple websites inside a single instance through the GUI and benefit from features like A/B testing, affiliate tracking tools, and a high performance template engine with CSS stylesheets processing & scripts minification.
Stars: ✭ 32 (+128.57%)
Mutual labels:  web-framework
jimhttp
A library collection and web microframework
Stars: ✭ 25 (+78.57%)
Mutual labels:  web-framework
multi-projects-architecture-with-Ktor
A Ktor real world example built on multi-projects architecture
Stars: ✭ 29 (+107.14%)
Mutual labels:  web-framework
alef-component
Alef Component for Modern Web Apps.
Stars: ✭ 46 (+228.57%)
Mutual labels:  web-framework
portals-pluto
Mirror of Apache Pluto
Stars: ✭ 24 (+71.43%)
Mutual labels:  web-framework
mojo.js
🦄 The Mojolicious real-time web framework for Node.js
Stars: ✭ 145 (+935.71%)
Mutual labels:  web-framework
Magento-Extra-RESTful
Many more REST resources for Magento's API
Stars: ✭ 32 (+128.57%)
Mutual labels:  api-server
skinny-micro
🎤 Micro Web framework to build Servlet applications in Scala, the core part of Skinny Framework 2
Stars: ✭ 57 (+307.14%)
Mutual labels:  web-framework
jflask
Flask-inspired web micro-framework for Java (deprecated)
Stars: ✭ 18 (+28.57%)
Mutual labels:  web-framework
framework
The Peak Framework
Stars: ✭ 20 (+42.86%)
Mutual labels:  web-framework

Maverick

Web API framework with a need for speed

Use

Maverick builds on top of the Plug.Conn.Adapter for your supported webserver and creates the webserver handler by reading annotations on functions you want to expose as part of your API. To publish a function, add use Maverick to your module and the @route attribute to the relevant functions. Pass a keyword list of options to the route attribute including the :path and you're off to the races.

Once you add the Maverick.Api to your application supervision tree and start the app, Maverick compiles your routes into a handler module and sends incoming requests to your functions, taking care to wrap the return values accordingly.

Example

With Maverick added to your application's dependencies, create a module that implements the use Maverick.Api macro and pass it, at a minimum, the name of your application:

  defmodule CoolApp.Api do
    use Maverick.Api, otp_app: :cool_app
  end

Then, in your application supervision tree, add your Maverick Api to the list of children:

  children =
    [
      maybe_a_database,
      other_cool_stuff,
      {CoolApp.Api, name: :cool_app_web, port: 443},
      anything_else
    ]

Now it's time to annotate the functions you want served over HTTP. These can be anywhere within your project structure that make sense to you, Maverick will compile them all into your callback handler. While it's considered best practice to structure your code to separate domain concerns and maintain good abstractions, in practice this organization has no effect on what functions are available to be routed to by Maverick. Add use Maverick to a module that will be serving functions and then any public function (sorry, no macros) with the @route annotation will do:

  defmodule CoolApp.BusinessLogics do
    use Maverick, scope: "api/v1"

    @route path: "do/stuff"
    def do_stuff(%{"stuff" => what_needs_doing}) do
      what_needs_doing |> transform_process_etc
    end
  end

Once the app is started, you can reach your function at the path, method, etc. configured on the route annotation, such as: curl -XPOST -d '{\"stuff\":\"transform-me!\"}' "http://host:port/api/v1/do/stuff"

Route Options

The following options can configure functions annotated with the @route attribute:

  • :path - The path, as a string, at which the function should be accessible. Prefix elements of the path with a colon (":") if they should be treated as variables on requests, such as api/customers/:customer_id (required).

  • :args - The format of the argument that will be passed to the internal function, which can be one of :params (the default), {:required_params: [atom()]}, or :request.

    • :params - The argument passed to the function will be a string-keyed map merging the path parameters map, query parameters map, and the request body map.

    • {:required_params, [atom()]} - The second element is a list of atoms representing keys that must appear and have non-nil values in the request params map, this subset of key/value pairs will be sent as a string-keyed map.

    • :request - The entire Maverick request struct will be sent. This is good for handling requests that need access to deeper elements of the HTTP request like the source IP, scheme, port, manipulating headers, etc.

  • :method - The HTTP method the function should respond to as an atom or a string. Defaults to "POST" (all methods are converted to uppercase strings so follow your personal tastes).

  • :success_code - In the event of success, the HTTP status code that will be returned (defaults to 200).

  • :error_code - In the event of an error (an explicit {:error, term()}), the HTTP status code that will be returned.

  • :scope - This special option is set at the module level (use Maverick.Api, scope: "path/prefix"), not on the @route attribute, to set a shared prefix for all routes handled within the module.

Return Values

Maverick aims to be simple to use, passing some form of map to your function (see :args in the above "Route Options" section) and taking virtually any JSON-encodable term as a result to return to the client.

That said, the following are acceptable return values for your routed functions; use the simplest one that meets your needs and it will be converted accordingly to allow the webserver to hand it back to the client:

  • response() - Any raw term will be assumed to be a successful request; must be encodable to JSON.

  • {:ok, response()} - An explicit success; the term must be encodable to JSON.

  • {:error, response()} - An explicit (non-exception) failure; the term must be encodable to JSON.

  • {code(), headers(), response()} - A 3-tuple with an explicit integer status code, map of response headers, and response body which, you guessed it, must be encodable to JSON.

In the absence of a full-detailed response return value, Maverick will apply the :success_code for the status code of {:ok, response()} and implicitly successful response() results and the :error_code for the status code of {:error, response()} results.

When response headers are returned, they are expected to be in the form of a map, as this is the format in which the function will receive request headers. They will be converted to [{String.t(), String.t()}] before handing back to the webserver to return to the client. If no response headers are returned, Maverick will automatically add the {"Content-Type", "application/json"} header.

Exceptions

In the event an exception is raised during handling of a request, the Handler functions will automatically rescue and construct a response by calling functions from the the Maverick.Exception protocol on the exception. See the exception protocol module for implementing it for specific exceptions.

But Why?

A full web framework with support for live content updates and server-side rendering is great, but sometimes you just want a way to handle JSON-based service requests over HTTP without all the bells and whistles.

Maverick aims to fill the niche between a full Phoenix Framework just for providing a web-based API and hand-rolling a Plug API.

To Do

  • Make it work
  • Support Elli webserver
  • Native telemetry integration
  • Implement basic auth middleware hooks in the API module (via Plug support)
  • Absinthe/GraphQL integration (via Plug support)
  • Profit?

Installation

The package can be installed by adding maverick to your list of dependencies in mix.exs:

def deps do
  [
    {:maverick, "~> 0.2.0"}
  ]
end

The docs can be found at https://hexdocs.pm/maverick.

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].