RepoPilot

How do their APIs compare?

About karumi/dexter · 2 messages · last activity 9/8/2026

Question

How do their APIs compare?

RepoPilot

These two projects aren't really comparable at a "which API is better" level — they solve completely different problems at different layers of an application stack — but here's how their surfaces actually differ in shape and intent:

karumi/dexter: a small, in-process fluent Java API

Dexter's "API" is a single-purpose client-side library exposed through a fluent builder, not a network/HTTP API. The entry point is the static class Dexter, which implements a chain of narrow builder interfaces (DexterBuilder, DexterBuilder.Permission, DexterBuilder.SinglePermissionListener, DexterBuilder.MultiPermissionListener) defined in [dexter/src/main/java/com/karumi/dexter/DexterBuilder.java:L24-L47]. Usage always follows the same shape:

Dexter.withContext(context).withPermission(permission).withListener(listener).check();

as shown in the README [README.md:L21-L45] and the sample app [sample/src/main/java/com/karumi/dexter/sample/SampleActivity.java:L87-L91]. Key characteristics:

  • Two entry points: Dexter.withContext(Context) (current) and the deprecated Dexter.withActivity(Activity) [dexter/src/main/java/com/karumi/dexter/Dexter.java:L56-L65].
  • Type-state builder pattern: each with... call returns a narrower interface so you can't call .check() before supplying a listener — enforced at compile time via the interface segregation in DexterBuilder.
  • Response objects, not exceptions: results come back as plain POJOs — PermissionGrantedResponse [dexter/src/main/java/com/karumi/dexter/listener/PermissionGrantedResponse.java:L16-L24] and PermissionDeniedResponse [dexter/src/main/java/com/karumi/dexter/listener/PermissionDeniedResponse.java:L16-L24] — delivered synchronously to callback listeners (PermissionListener, MultiplePermissionsListener), not returned from check() itself (which is void).
  • Aggregation object: for multi-permission requests, MultiplePermissionsReport [dexter/src/main/java/com/karumi/dexter/MultiplePermissionsReport.java:L30-L90] bundles granted/denied lists and exposes convenience predicates like areAllPermissionsGranted() and isAnyPermissionPermanentlyDenied().
  • Builder-of-builder helpers: convenience listener implementations, like DialogOnAnyDeniedMultiplePermissionsListener.Builder, offer their own fluent sub-API for configuring a rationale dialog [dexter/src/main/java/com/karumi/dexter/listener/multi/DialogOnAnyDeniedMultiplePermissionsListener.java:L75-L154].

There is no versioning, no serialization format, and no network boundary — it's all in-memory, single-app-process API design centered on ergonomics and misuse-resistance via the type-state builder.

yunaiv/ruoyi-vue-pro: a server-side HTTP API with a uniform envelope

ruoyi-vue-pro is a Spring-based backend, so its "API" is HTTP endpoints (@RestControllers, not shown directly in the retrieved chunks, but the response contract is) wrapped uniformly in CommonResult<T> [yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java:L20-L122]. This is a classic backend response envelope pattern:

  • Every response carries a code, msg, and data field [CommonResult.java:L20-L37].
  • Success is constructed via CommonResult.success(data) which hardcodes GlobalErrorCodeConstants.SUCCESS [CommonResult.java:L69-L75].
  • Failure has multiple overloads — from a raw code/message, from an ErrorCode enum with templated params, or from a ServiceException [CommonResult.java:L39-L67, L114-L117] — centralizing error-code discipline across all controllers.
  • checkError() bridges the HTTP response model back into Java's exception flow by throwing ServiceException when the result represents an error [CommonResult.java:L87-L95], and `getCheckedData()

Want to ask your own question?

Open chat for karumi/dexter

Public Q&A. Generated by RepoPilot from the actual source of karumi/dexter. AI answers can be incomplete or stale — verify before relying on them.