FlopRest - Stripe-style REST parameters for Flop

Hey folks!

I built FlopRest, a small library that transforms Stripe-style query parameters into Flop format.

The Problem

Flop is excellent for filtering, sorting, and paginating Ecto queries. But when building JSON APIs, its native format creates friction:

?filters[0][field]=status&filters[0][op]==&filters[0][value]=published&filters[1][field]=starts_at&filters[1][op]=>=&filters[1][value]=2024-01-01&order_by[0]=starts_at&order_directions[0]=desc&first=20

Frontend developers expect something like Stripe or GitHub:

?status=published&starts_at[gte]=2024-01-01&sort=-starts_at&limit=20

Same query. FlopRest bridges that gap—same Flop power underneath, better DX on top.

Usage

def index(conn, params) do
  flop_params = FlopRest.normalize(params)

  with {:ok, {events, meta}} <- Flop.validate_and_run(Event, flop_params, for: Event) do
    json(conn, %{
      data: events,
      links: %{
        self: FlopRest.build_path(conn.request_path, meta.flop),
        next: meta.has_next_page? && FlopRest.build_path(conn.request_path, meta.next_flop),
        prev: meta.has_previous_page? && FlopRest.build_path(conn.request_path, meta.previous_flop)
      }
    })
  end
end

What It Supports

  • Filters: status=published, amount[gte]=100
  • Sorting: sort=-created_at,name (minus for desc)
  • Pagination: Cursor (limit + starting_after), page-based, and offset-based
  • Pagination links: build_path/2 generates next/prev URLs from Flop meta

All 21 Flop operators are supported.

When to Use It

Building a LiveView/HTML app? Flop Phoenix already handles the UI side.

Building a JSON API consumed by React/Vue/Svelte/mobile apps? FlopRest makes your API feel native to frontend developers—standard URLSearchParams just works, no custom serialization needed.

Design

Pure transformation layer. Invalid params pass through for Flop to validate.


https://github.com/guess/flop_rest

6 Likes