81 KiB
Changelog
1.0.1 - 2026-07-31
A documentation and CLI-ergonomics patch. No behavior changes to the framework runtime.
Fixed
generate scaffold/controllerno longer error on the old--apiflag. The 1.0 adaptive-generator rebuild removed the--api/--html/--htmx(and-k/--kind) flags — scaffold now auto-detects headless vs. clientside fromfrontend/, and controllers are always JSON API controllers — but the docs (including the Your first app tutorial) still showed--api, so copy-pasting them failed witherror: unexpected argument '--api' found. The generators now accept the old flags for compatibility:--apiis a no-op (it's the headless default) and--html/--htmxreturn a clear message pointing at the React SPA frontend that replaced server-rendered views. (#1790)- Docs resync. Removed every reference to the removed scaffold/controller
kind flags and the deleted
ScaffoldKindenum /mappings.jsonacross the tutorials, how-to guides, and CLI/generators reference; corrected the field-type reference to describeloco-gen/src/column.rs(including thatarray:intis now a 64-bitBigIntarray, consistent with the scalarint→i64change).
1.0.0 - 2026-07-25
1.0.0 is the first stable Loco release — a single, intentionally-breaking milestone. Its headline is the move to Sea-ORM 2.0, alongside first-class LLM/agent support, priority queues, a broad dependency modernization, and a deep hardening pass across the queue, storage, config, error, remote-IP, and middleware subsystems. Follow the step-by-step 0.16 → 1.0 upgrade guide.
Breaking Changes
- Sea-ORM 2.0 + sqlx 0.9. Bump
sea-orm/sea-orm-migrationto2.0(app +migrationcrate), directsqlxto0.9, update the Sea-ORM CLI, and regenerate entities. Raw-Statementcalls gain a_rawsuffix; runtime SQL strings needAssertSqlSafe. MSRV is 1.94 (sea-orm 2.0.0 declares it). (Adopted from the SeaQL fork and #1698.) - Generated primary/foreign keys are now 64-bit (BIGINT /
i64). Also theint/unsignedfield types generate 64-bit columns. Only affects newly generated code; existing tables are untouched. - Priority queues — Redis backend change. The Redis worker moved from Lists
to Sorted Sets (ZSET) to support priority; drain existing Redis queues before
upgrading. Postgres/SQLite auto-migrate a
prioritycolumn (no action). (#1693) Worker::perform_later()returns the job ID (Result<String>), andQueue::enqueue()returnsResult<Option<String>>. Existingperform_later(...).await?;keeps working. (#1624, fixes #1623)PageResponse<T>exposesmeta: PagerMetainstead of flattotal_pages/total_items(also carriespage/page_size). (#1685, fixes #1683)- View engine: use
engines::TeraView::build_with_post_process(...)instead ofTeraView::build()?.post_process(...)inafter_routes. - Dependency majors:
thiserror1→2,tower0.4→0.5,heck→0.5,byte-unit4→5,ipnetwork0.20→0.21,strum→0.27,redis0.31→1,bb8-redis→0.26,opendal0.54→0.57;serde_yaml→serde_yaml_ng. Transitive for most apps. - Removed the dead
loco-clicrate (superseded byloco-new, the publishedlocobinary). ExtraDbInitializerremoved; useMultiDbInitializer. The single-extra-connection initializer (initializers.extra_db, which layered a bareExtension<DatabaseConnection>) is gone. UseMultiDbInitializerwith a one-entryinitializers.multi_dbmap instead, and extract the connection withExtension<MultiDb>+multi_db.get("<name>"). This collapses two near-identical initializers into one named-connections abstraction.AppContextis now#[non_exhaustive]. Construct it withAppContext::builder(environment, db, config)(orbuilder(environment, config)without thewith-dbfeature) followed by optional.queue_provider(..)/.mailer(..)/.storage(..)/.cache(..)/.shared_store(..)and.build(). Direct struct-literal construction and exhaustive pattern matches onAppContextfrom outside the crate no longer compile; field access (ctx.db,ctx.config,State/FromRefextraction) is unchanged. This makes future context fields non-breaking to add.- Storage
MirrorStrategyandBackupStrategymerged intoReplicatedStrategy. The two strategies were the same primary-plus-secondaries replication engine; they are now onestorage::strategies::replicated::ReplicatedStrategywith a singleFailurePolicyenum. Migrate:MirrorStrategy::new(p, s, MirrorAll)→ReplicatedStrategy::mirror(p, s, FailurePolicy::FailIfAny);BackupStrategy::new(p, s, BackupAll)→ReplicatedStrategy::backup(p, s, FailurePolicy::FailIfAny). OldFailureModemaps:AllowMirrorFailure/AllowBackupFailure→AllowAll,AtLeastOneFailure→AllowSingleFailure,CountFailure(n)→FailAtFailures(n). Secondary writes for the former backup strategy now run concurrently (previously sequential); the collected errors and failure decision are unchanged. - Local storage driver no longer defaults its root to
/.storage::drivers::local::new()previously rooted the filesystem store at/, so any key — including one derived from user input — resolved against the whole disk (e.g. downloading keyetc/passwdread/etc/passwd). It now roots at the current working directory. Apps that relied on absolute-path keys should switch tolocal::new_with_prefix("/your/root")to opt back into an explicit absolute root. - Background queue reworked into a
QueueProvideradapter interface. Thebgworker::Queueenum (Postgres/Sqlite/Redis/None) is now a newtype overArc<dyn QueueProvider>, so backends are pluggable (implementQueueProviderand wrap withQueue::from_provider). All existing methods (enqueue,register,run,ping,cancel_jobs,clear_by_status,requeue, …) keep the same signatures and behavior. Only two source-level changes affect callers: construct a no-op queue withQueue::empty()instead ofQueue::None, and code that pattern-matched the enum variants (e.g.Queue::Postgres(pool, ..)to reach the raw pool) no longer compiles — use the provider methods instead. - Fallback middleware defaults to
404. When the built-in fallback is enabled without an explicitcode, it now returns404 Not Found(matching its docs and the bundled not-found page) instead of200 OK. Apps that relied on the enabled fallback returning200must setcode: 200explicitly. The file-based fallback is unaffected (ServeFilereports its own status). {env}.local.yamlnow deep-merges over{env}.yaml. Previously the first existing file won and the other was ignored, so a.local.yamlhad to restate the whole config. Both files are now layered with local precedence: mappings merge recursively; scalars and sequences in local replace the base value (sequences are not concatenated). Base keys now persist unless explicitly overridden.- More accurate HTTP status codes for errors.
IntoResponse for Errorpreviously collapsed ~28 of 35 variants to500.Model(EntityNotFound)now returns404,Model(EntityAlreadyExists)returns409, model validation and form-body rejections return4xx(matching JSON rejections) instead of500. Genuinely-internal errors still return a generic500. Handlers that asserted on the old500s will observe the corrected codes. JWT::algorithm()restricted to the HMAC family. It now takes a newloco_rs::auth::jwt::JWTAlgorithmenum (HS256/HS384/HS512) instead ofjsonwebtoken::Algorithm. Asymmetric algorithms — which could never work with Loco's shared base64 secret and silently produced broken tokens — are no longer representable.remote_ipmiddleware rebuilt onaxum-client-ip;trusted_proxiesremoved. Previously this middleware walkedX-Forwarded-Forright-to-left, skipping any address in a configurabletrusted_proxiesCIDR list (or a built-in RFC-1918 + loopback list), so it could see through a chain of one or more trusted proxies. It now trusts exactly one configured source (source: ClientIpSource, defaultRightmostXForwardedFor) and does no CIDR filtering — for the default it takes the last comma-separated value of the lastX-Forwarded-Forheader verbatim, private or not. Single reverse-proxy deployments are unaffected. Multi-hop topologies (CDN → LB → ingress) must now configure their innermost hop to set the client IP (e.g. nginxset_real_ip_from/real_ip_recursive), or pointsourceat a provider header (CfConnectingIp,CloudFrontViewerAddress,XRealIp,ConnectInfo, …). Note: an old config'strusted_proxies:key is silently ignored (unknown field), so reviewremote_ipbefore upgrading — this is a silent security-relevant behavior change, not a load error. TheRemoteIPextractor and itsDisplayoutput are unchanged.auth_jwtfeature renamed toauth. Updatefeatures = ["auth_jwt"]→["auth"](it gates JWT auth and theApiTokenextractor, as before).- Background-queue features collapsed.
bg_pg/bg_sqlt→worker(Postgres+SQLite; free oncesqlxis compiled),bg_redis→worker_redis(addsdep:redis).defaultnow hasworker(not Redis). A Redis queue needsworker_redis; the queue backend is selected at runtime byqueue.kind. - Mailer
Template::new(dir)now returnsResult(callTemplate::new(dir)?). Email templates render through a full Tera instance so they support inheritance and shared templates. Standard usage viaMailer::mail_templateis unchanged. (#1694) Vars::cli_argreturnsResult<&str>(wasResult<&String>). Callers that relied on&String(e.g..clone()into aString) should use.to_owned(). (#1732)
Added
- First-class LLM / agent support. Root
AGENTS.mdteaches agents to build Loco apps;llms.txt/llms-full.txtare served from the site (llmstxt.org). Everyloco newapp ships an app-levelAGENTS.md. - Priority queues with
Worker::perform_later_with_priority(...); mailer jobs default to priority100. (#1693) - Mailer implicit TLS (SMTPS / port 465) via
mailer.smtp.tls. (#1774, fixes #1773) - Run the scheduler without a worker —
--schedulerflag +StartMode::ServerAndScheduler/WorkerAndScheduler. (#1742, fixes #1737) - Email headers support in the mailer (#1700).
- Multi-recipient emails.
Mailer::mail_multi/mail_template_multiand theMultiEmail/MultiArgstypes send one email to multiple To/CC/BCC recipients (processed by a dedicatedMultiMailerWorker). (#1764) - Email template inheritance & shared templates. Mailer templates support
Tera
{% extends %}/{% block %}and can share a common layout viaMailer::mail_template_with_shared/Template::new_with_shared.loco generate mailernow scaffolds asrc/mailers/shared/base layout that the welcome template extends. (#1694) - "Create user" task (#1670).
UuidUniqWithDefaultandUuidWithDefaulttypes (#1642).- Allow overriding a secure header (#1659).
Mailer::deliver_now/mail_template_nowfor synchronous sends. ComplementsMailer::mail/mail_template(which enqueue via the background worker, like Railsdeliver_later) with an inline send that bypasses the queue (Railsdeliver_now).MiddlewareStackExtfor surgical middleware-stack edits. InsideHooks::middlewares, tweak the default stack instead of rebuilding it:stack.insert_before("cors", ..),.insert_after(..),.replace(..), and.delete("logger")— matched by middleware name (Rails'config.middleware.insert_before/delete). Available via the prelude.- Optional JWT extraction.
JWTnow implementsOptionalFromRequestParts, so a handler can takeOption<JWT>to serve authenticated and anonymous callers from one endpoint (Somewhen a valid token is present,Noneotherwise). - Ergonomic verb-explicit route methods.
Routesnow hasget/post/put/delete/patch/head/options/tracebuilder methods —Routes::new().get("/ping", ping)alongside the existing.add("/ping", get(ping)). They record the HTTP verb directly (exactcargo loco routesoutput without relying on the debug-format regex). Purely additive;addis unchanged. - Opt-in background-job reaper (visibility timeout). Each queue backend's
config accepts a
reaper: { age_minutes, interval_seconds }block. When set, the worker periodically requeues jobs stranded inProcessing(e.g. by a crashed worker) back toQueued, instead of requiring a manualcargo loco jobs requeue. Disabled by default — existing behavior is unchanged. - TLS to managed Postgres and Redis. Postgres TLS works via the connection
URL (
sslmode=require,sslrootcert=...) with no feature flag, and a newredis_tlsfeature enablesrediss://for both the queue and cache Redis backends (webpki roots, pure-Rustringprovider — no C toolchain). New how-to: "Connect to Postgres and Redis over TLS". (#1191, #1341) - Typed, streaming
db::dump::<A>()— counterpart todb::seed::<A>()that streams rows through their entityModelstraight to disk (memory bounded to a single row) with full type fidelity. NewHooks::dump(default dumps every table; override it to calldb::dumpper entity) backscargo loco db seed --dump. (#1691) logger::init_layer/logger::init_env_filterare now public building blocks, so an app overridingHooks::init_loggercan reuse Loco's formatting and filter policy while adding its own layers (e.g.tracing-flame, OTLP). (#1753)
Changed
- Wrap
TeraViewinArcto reduce runtime memory usage (#1703). - Refactor users model to reuse
find_by_api_keyinAuthenticable(#1706). - Split error detail generic parameters (#1709).
- Update
loco-newfor the new Rhai version (#1704). - Replaced hand-rolled
Cargo.lockparsing with thecargo-lockcrate; retiredduct_sh. Error→ HTTP-status mapping is now exhaustive. TheIntoResponse for Errormatch dropped its trailing_ => 500wildcard: every variant (and every nestedModelErrorvariant) is now classified explicitly, so adding a new error variant is a compile error until its status is chosen — it can no longer silently default to500. TheErrorenum is also reorganized into client-facing vs internal/infra regions. Behavior is unchanged (all infra errors still map to500); no variant was renamed, so existing code is unaffected.- Rust edition 2024.
loco-rs,loco-gen,xtask, and theloconew-app generator now compile on edition 2024 (MSRV floor unchanged at 1.94; edition 2024 needs ≥ 1.85). Editions are per-crate, so apps depending on Loco need not change. Newly generated apps stay on edition 2021 for now. - Deduplicated the Postgres and SQLite background-queue providers: the shared
Job/JobRegistry/RunOptsnow live in one module behind aDrivertrait (internal refactor, no behavior or API-path change). - In-memory cache now uses
moka::future::Cacheinstead of wrapping the synchronous cache behind#[async_trait](removes a sync-behind-async smell; no API change). - Cookie token extraction now uses
axum_extra'sCookie::value()instead of hand-parsing the cookie string (byte-identical behavior). - Internal de-duplication pass (no public-API-path or behavior change unless
noted): the response helpers in
formatare now single-sourced throughRenderBuilder; theJWT/JWTWithUserextractors share one validate/decode helper; the six validate extractors are generated from shared decoder fns + two error-tier macros; the byte-identicalJobstruct is shared across the SQL and Redis queue backends; the twincli::mainfunctions share onedispatch_common; and duplicate env-var name constants were removed. format's two response paths were converged onto axum's canonical behavior:RenderBuilder::jsonandRenderBuilder::redirect_with_header_keyare now infallible with respect to bad input (they return a500response, matchingaxum::Json/axum::response::Redirect) instead of returningErr.
Fixed
db seed --dumpdatetime round-trip on SQLite. Loco's timestamptz columns default toCURRENT_TIMESTAMP, which SQLite stores as space-separated text ("YYYY-MM-DD HH:MM:SS"); dumps captured that verbatim and then failed chrono's RFC3339 parse on re-seed (Json("premature end of input")). Dumps now normalize such datetimes to RFC3339 (already-RFC3339 text is untouched). (#1736, #1691)cargo fmterror inloco-new(#1669).- UUID pattern in form field generation (#1665).
- Clippy warnings for recent Rust (#1705).
- Add tests for the auth extractor (#1671).
- Postgres/SQLite queue backends now behave consistently. Two divergences
between the Postgres and SQLite job backends are fixed: (1)
enqueueon Postgres previously swallowed a tag-serialization error (storingtags = null); it now propagates the error like SQLite. (2)complete_jobwithout a repeat interval on Postgres stampedrun_at = NOW()on the completed row while SQLite left it untouched; Postgres now leavesrun_atas-is, matching SQLite (the interval path still reschedulesrun_aton both). The sharedto_jobrow mapper is now single-sourced across both backends. - Storage mirror fan-out no longer stops at the first failing secondary.
rename,copy, andupload_streamchecked the failure mode inside the secondary loop and returned early on the first failure, silently leaving later mirrors stale (upload/deletewere already correct). All five mutating methods now share one helper that attempts every secondary (concurrently) and applies the failure mode once. - Postgres
BOOLEANcolumns are no longer dropped fromdump_tables. The decode probe chain had noboolarm, so PG booleans (which don't fall back to the numeric arms like SQLite's integer-backed booleans) were silently omitted. Hooks::on_shutdownnow runs in worker-only start modes.WorkerOnlyandWorkerAndSchedulerbypassedH::serve(the hook's only caller); the shutdown hook is now invoked on their shutdown path too.- Postgres admin/maintenance URI is derived with the
urlcrate. Building it viadb_uri.replace(db_name, "/postgres")corrupted the URI when the database name also appeared in the host or credentials. - Foreign-key names are normalized consistently.
reference_idreceived a normalized table name increate_tablebut raw names inadd_reference/remove_reference, so irregular plurals produced mismatched FK column/constraint names between creation and later add/remove. ViewEngineextractor now rejects gracefully (HTTP500) when the opt-in Tera layer is absent, instead of declaringInfallibleand then panicking.cargo loco routeslists every HTTP verb of a multi-method route (route introspection previously reported only the first).- Removed a fossilized 3-second
sleepon every Redis queue boot (a leaked test-isolation artifact; Postgres/SQLite had no equivalent). - Password redaction in test snapshots (
cleanup_user_model) now targets the quoted value precisely; the previous pattern had a degenerate quantifier that swallowed the field followingpassword. - Postgres test-database cleanup now completes synchronously (a joined worker
thread) instead of a fire-and-forget task, so parallel test runs no longer
leak databases;
PostgresTestalso builds its connection strings with theurlcrate rather than a corruption-prone substring replace. RenderBuilder::templatenow threads the builder's chainedstatus/header/etag/cookiesthrough to the response; it previously delegated to the freehtml()and silently dropped them.llms.txt: twoCore conceptslinks pointed at doc pages that don't exist (the-app/configuration/,the-app/testing/); repointed to the sections that actually document them. A newcargo xtask llms-checkCI step now verifies the curated LLM docs against the docs tree so these links can't drift silently.
Removed
Errorenum narrowing. Removed four low-value/dependency-leaking variants that all mapped to HTTP 500 and were never matched:Error::EnvVar,Error::SemVer,Error::TaskJoinError, andError::Hash(hashing errors now surface asError::Message).Errorremains#[non_exhaustive], so exhaustive matches already require a wildcard arm and are unaffected.- Deleted shipped-but-dead code: the never-compiled
controller/middleware/_archive/content_etag.rsmodule and a commented-out block of backtrace-blocklist regexes.
v0.16.4
- Feat: decouple JWT authentication from database dependency. https://github.com/loco-rs/loco/pull/1546
- Fix: add sqlx dependency to with-db feature. https://github.com/loco-rs/loco/pull/1557
- Remove the deprecated
--linkgenerate command and fix the table name creation. https://github.com/loco-rs/loco/pull/1556 - Support underscore for migration join table. https://github.com/loco-rs/loco/pull/1562
- Fix: resolve deployment CLI argument parsing issue. https://github.com/loco-rs/loco/pull/1566
- Add database enum support (Postgres only). https://github.com/loco-rs/loco/pull/1593
- Remove duplicated #[async_trait::async_trait]. https://github.com/loco-rs/loco/pull/1593
- Clippy fixes for Rust 1.89. https://github.com/loco-rs/loco/pull/1593
- Improvement: do not hot-reload unless files have changed. https://github.com/loco-rs/loco/pull/1552
- Feat: add --without-tz flag for controlling timestamp generation. https://github.com/loco-rs/loco/pull/1592
- Support extra fields when generating the join table migration. https://github.com/loco-rs/loco/pull/1595
- Convert validator to trait-based API (add ValidatorTrait, keep derive adapter, update docs). https://github.com/loco-rs/loco/pull/1597
- Rename dockerfile to Dockerfile. https://github.com/loco-rs/loco/pull/1574
- Enable edit CORS expose headers. https://github.com/loco-rs/loco/pull/1599
- Adding new imports about multipart. https://github.com/loco-rs/loco/pull/1600
- Adding readiness default endpoint. https://github.com/loco-rs/loco/pull/1563
- Add Route methods to make collecting and nesting easier. https://github.com/loco-rs/loco/pull/1608
- Add streaming support for both download and upload. https://github.com/loco-rs/loco/pull/1610
- Fix Clippy for Rust 1.90. https://github.com/loco-rs/loco/pull/1630
- Loco CLI: Update rhai version. https://github.com/loco-rs/loco/pull/1631
v0.16.3
- Support nullable foreign keys with
references?syntax. https://github.com/loco-rs/loco/pull/1544 - HOTFIX: Breaking changes Fixed a critical issue introduced in version
v0.16.2that causedcargo build --releaseto fail after merging #1540. https://github.com/loco-rs/loco/pull/1551 - Add an API to re-send verification mail. https://github.com/loco-rs/loco/pull/1456
- Adding to ci cargo build --release. https://github.com/loco-rs/loco/pull/1553
Breaking Changes
In file src/initializers/view_engine.rs, modify the method after_routes:
Before
async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
#[allow(unused_mut)]
let mut tera_engine = engines::TeraView::build()?;
if std::path::Path::new(I18N_DIR).exists() {
let arc = ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US"))
.shared_resources(Some(&[I18N_SHARED.into()]))
.customize(|bundle| bundle.set_use_isolating(false))
.build()
.map_err(|e| Error::string(&e.to_string()))?;
#[cfg(debug_assertions)]
tera_engine
.tera
.lock()
.expect("lock")
.register_function("t", FluentLoader::new(arc));
#[cfg(not(debug_assertions))]
tera_engine
.tera
.register_function("t", FluentLoader::new(arc));
info!("locales loaded");
}
Ok(router.layer(Extension(ViewEngine::from(tera_engine))))
}
After (use post_process to add i18n initialization code)
async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
let tera_engine = if std::path::Path::new(I18N_DIR).exists() {
let arc = std::sync::Arc::new(
ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US"))
.shared_resources(Some(&[I18N_SHARED.into()]))
.customize(|bundle| bundle.set_use_isolating(false))
.build()
.map_err(|e| Error::string(&e.to_string()))?,
);
info!("locales loaded");
engines::TeraView::build()?.post_process(move |tera| {
tera.register_function("t", FluentLoader::new(arc.clone()));
Ok(())
})?
} else {
engines::TeraView::build()?
};
Ok(router.layer(Extension(ViewEngine::from(tera_engine))))
}
v0.16.2
- Update auth import in the Authentication document. https://github.com/loco-rs/loco/pull/1531
- Adding cache control header to the static asset middleware. https://github.com/loco-rs/loco/pull/1535
- Fix borrow checker when sending config to handle_job_command when feature with-db is off. https://github.com/loco-rs/loco/pull/1536
- feat: add initializer health checks to doctor command. https://github.com/loco-rs/loco/pull/1537
- Update shuttle template to 0.56. https://github.com/loco-rs/loco/pull/1518
- Encapsulate post-processing into Tera engine creation. https://github.com/loco-rs/loco/pull/1540
- Adding QueryValidateWithMessage. https://github.com/loco-rs/loco/pull/1521
- Add S3 driver with credentials and endpoint support. https://github.com/loco-rs/loco/pull/1539
v0.16.1
- fix clippy result_large_err. https://github.com/loco-rs/loco/pull/1496
- chore: remove async-std. https://github.com/loco-rs/loco/pull/1492
- fix: Bump shuttle version to 0.55.0. https://github.com/loco-rs/loco/pull/1488
- Change the Docker building image to 1.87. https://github.com/loco-rs/loco/pull/1475
- Fix Clippy warnings for Rust 1.88 stable. https://github.com/loco-rs/loco/pull/1519
- Remove Migrator from boot_test_* doc comments. https://github.com/loco-rs/loco/pull/1512
- fix: use rust-lld linker on Windows. https://github.com/loco-rs/loco/pull/1508
- Fix precompressed in static assets. https://github.com/loco-rs/loco/pull/1524
- Support multiple JWT locations. https://github.com/loco-rs/loco/pull/1497
v0.16.0
Note: For detailed upgrade steps for breaking changes, see the upgrade guide.
- chore: improve readability and performance by using map_err in Model. https://github.com/loco-rs/loco/pull/1311
- Allow testing the controller by passing a cookie. https://github.com/loco-rs/loco/pull/1326
- Support BigInt in the scaffold Array. https://github.com/loco-rs/loco/pull/1304
- Add
escapeTera function to the scaffold list template. https://github.com/loco-rs/loco/pull/1337 - Return a specific error when logging in with a non-existent email. https://github.com/loco-rs/loco/pull/1336
- Return a specific error when trying to verify with an invalid token. https://github.com/loco-rs/loco/pull/1340
- Clippy 1.86. https://github.com/loco-rs/loco/pull/1353
- Fix the DB creation. https://github.com/loco-rs/loco/pull/1352
- YAML responses. https://github.com/loco-rs/loco/pull/1360
- Swap to the validators' built-in email validation. https://github.com/loco-rs/loco/pull/1359
- Cancellation tokens for the Postgres and SQLite background workers. https://github.com/loco-rs/loco/pull/1365
- docs: testing auth routes. https://github.com/loco-rs/loco/pull/1303
- Add comprehensive tests for the task module. https://github.com/loco-rs/loco/pull/1386
- Add comprehensive test coverage for the data module. https://github.com/loco-rs/loco/pull/1387
- Add validator extractors test suite. https://github.com/loco-rs/loco/pull/1388
- Breaking changes Replace sidekiq job management: existing Redis jobs incompatible. https://github.com/loco-rs/loco/pull/1384
- Breaking changes Add generic type support to the Cache API: cache method calls need type parameters. https://github.com/loco-rs/loco/pull/1385
- Adding cache redis driver + configuration instead of enabling from code. https://github.com/loco-rs/loco/pull/1389
- Ability to configure pragma for SQLite. https://github.com/loco-rs/loco/pull/1346
- Breaking changes swap to validators builtin email validation: custom email validator syntax changed. https://github.com/loco-rs/loco/pull/1359
- Optimize worker tag filtering string handling. https://github.com/loco-rs/loco/pull/1396
- Add test coverage for db.rs. https://github.com/loco-rs/loco/pull/1400
- Allow storage of arbitrary custom objects in AppContext. https://github.com/loco-rs/loco/pull/1404
- Improve deployment generator CLI. https://github.com/loco-rs/loco/pull/1413
- Move auth and validate to the extractor folder. https://github.com/loco-rs/loco/pull/1414
- Hot reload on extended Tera templates. https://github.com/loco-rs/loco/pull/1416
- Breaking changes Update the
init_loggerto useAppContextinstead of config: function signature changed. https://github.com/loco-rs/loco/pull/1418 - Support embedded assets. https://github.com/loco-rs/loco/pull/1427
- Removed dependencies:
- Dependency updates:
- Support custom flags from
sea-orm entity. https://github.com/loco-rs/loco/pull/1442 - Better
loco newcleanup folders. https://github.com/loco-rs/loco/pull/1429 - Remove legacy mailer derive macro code. https://github.com/loco-rs/loco/pull/1472
- Make extract_token and get_jwt_from_config fn public. https://github.com/loco-rs/loco/pull/1495
v0.15.0
- Added total_items to pagination view & response. https://github.com/loco-rs/loco/pull/1197
- Flatten (de)serialization of custom user claims. https://github.com/loco-rs/loco/pull/1159
- Updated validator to 0.20. https://github.com/loco-rs/loco/pull/1199
- Scaffold v2. https://github.com/loco-rs/loco/pull/1209
- Fix generator Docker deployment to support both server-side and client-side rendering. https://github.com/loco-rs/loco/pull/1227
- Docs: num_workers worker configuration. https://github.com/loco-rs/loco/pull/1242
- Smoother model validations. https://github.com/loco-rs/loco/pull/1233
- Docs: num_workers worker configuration. https://github.com/loco-rs/loco/pull/1242
- Ignore SQLite WAL and SHM files and update Cargo watch crate docs. https://github.com/loco-rs/loco/pull/1254
- Remove fs-err crate. https://github.com/loco-rs/loco/pull/1253
- Allows to run scheduler as part of cargo loco start. https://github.com/loco-rs/loco/pull/1247
- Added prefix and route nesting to AppRoutes. https://github.com/loco-rs/loco/pull/1241
- Replace hyper crate with axum. https://github.com/loco-rs/loco/pull/1258
- Remove mime crate. https://github.com/loco-rs/loco/pull/1256
- Support async tests. https://github.com/loco-rs/loco/pull/1237
- Change job queue status from cli. https://github.com/loco-rs/loco/pull/1228
- Handle panics in queue worker. https://github.com/loco-rs/loco/pull/1274
- Schema with defaults. https://github.com/loco-rs/loco/pull/1273
- Add data subsystem. https://github.com/loco-rs/loco/pull/1267
- Add "endpoint" arg to azure storage builder.https://github.com/loco-rs/loco/pull/1317
- Improve readability and performance by using map_err in Model. https://github.com/loco-rs/loco/pull/1311
Breaking Changes
In module loco_rs::auth::jwt in struct JWT, the impl method generate_token signature has changed.
Migration:
Before
jwt.generate_token(&expiration, pid.clone(), None);
After
jwt.generate_token(expiration, pid.clone(), Map::new());
// ^ no "&" ^ serde_json::map (doesn't allocate in constructor)
v0.14.1
- Fix: bump shuttle to 0.51.0. https://github.com/loco-rs/loco/pull/1169
- Return 422 status code for JSON rejection errors. https://github.com/loco-rs/loco/pull/1173
- Address clippy warnings for Rust stable 1.84. https://github.com/loco-rs/loco/pull/1168
- Bump shuttle to 0.51.0. https://github.com/loco-rs/loco/pull/1169
- Return 422 status code for JSON rejection errors. https://github.com/loco-rs/loco/pull/1173
- Return json validation details response. https://github.com/loco-rs/loco/pull/1174
- Fix example command after generating schedule. https://github.com/loco-rs/loco/pull/1176
- Fixed independent features. https://github.com/loco-rs/loco/pull/1177
- Custom response header for redirect. https://github.com/loco-rs/loco/pull/1186
- Added run_on_start feature to scheduler. https://github.com/loco-rs/loco/pull/1184
- feat: public jwt extractor from non-mutable reference to parts. https://github.com/loco-rs/loco/pull/1190
v0.14
-
feat: smart migration generator. you can now generate migration based on naming them for creating a table, adding columns, references, join tables and more. https://github.com/loco-rs/loco/pull/1086
-
feat:
cargo loco routeswill now pretty-print routes -
fix: guard jwt error behind feature flag. https://github.com/loco-rs/loco/pull/1032
-
fix: logger file_appender not using the seperated format setting. https://github.com/loco-rs/loco/pull/1036
-
seed cli command. https://github.com/loco-rs/loco/pull/1046
-
Updated validator to 0.19. https://github.com/loco-rs/loco/pull/993
Breaking Changes
Bump validator to 0.19 in your local
Cargo.toml -
Testing helpers: simplified function calls + adding html selector. https://github.com/loco-rs/loco/pull/1047
Breaking Changes
Updated Import Paths
The testing module import path has been updated. To adapt your code, update imports from:
use loco_rs::testing;to:
use testing::prelude::*;Simplified Function Calls
Function calls within the testing module no longer require the testing:: prefix. Update your code accordingly. For example:
Before:
let boot = testing::boot_test::<App>().await.unwrap();After:
let boot = boot_test::<App>().await.unwrap(); -
implement commands to manage background jobs. https://github.com/loco-rs/loco/pull/1071
-
magic link. https://github.com/loco-rs/loco/pull/1085
-
infer migration. https://github.com/loco-rs/loco/pull/1086
-
Remove unnecessary calls to 'register_tasks' functions in scheduler. https://github.com/loco-rs/loco/pull/1100
-
implement commands to manage background jobs. https://github.com/loco-rs/loco/pull/1071
-
expose hello_name for SMTP client config. https://github.com/loco-rs/loco/pull/1057
-
use reqwest with rustls rather than openssl. https://github.com/loco-rs/loco/pull/1058
-
more flexible config, take more values from ENV. https://github.com/loco-rs/loco/pull/1058
-
refactor: Use opendal to replace object_store. https://github.com/loco-rs/loco/pull/897
-
allow override loco template. https://github.com/loco-rs/loco/pull/1102
-
support custom config folder. https://github.com/loco-rs/loco/pull/1081
-
feat: upgrade to Axum 8. https://github.com/loco-rs/loco/pull/1130
-
create load config hook. https://github.com/loco-rs/loco/pull/1143
-
initial impl new migration dsl. https://github.com/loco-rs/loco/pull/1125
-
allow disable limit_payload middleware. https://github.com/loco-rs/loco/pull/1113
v0.13.2
- static fallback now returns 200 and not 404 https://github.com/loco-rs/loco/pull/991
- cache system now has expiry https://github.com/loco-rs/loco/pull/1006
- fixed: http interface binding https://github.com/loco-rs/loco/pull/1007
- JWT claims now editable and public https://github.com/loco-rs/loco/issues/988
- CORS now not enabled in dev mode to avoid friction https://github.com/loco-rs/loco/pull/1009
- fixed: task code generation now injects in all cases https://github.com/loco-rs/loco/pull/1012
BREAKING
In your app.rs add the following injection comment at the bottom:
fn register_tasks(tasks: &mut Tasks) {
tasks.register(tasks::user_report::UserReport);
tasks.register(tasks::seed::SeedData);
tasks.register(tasks::foo::Foo);
// tasks-inject (do not remove)
}
- fix: seeding now sets autoincrement fields in the relevant DBs https://github.com/loco-rs/loco/pull/1014
- fix: avoid generating entities from queue tables when the queue backend is database based https://github.com/loco-rs/loco/issues/1013
- removed: channels moved to an initializer https://github.com/loco-rs/loco/issues/892 BREAKING See how this looks like in https://github.com/loco-rs/chat-rooms
v0.13.0
- Added SQLite background job support https://github.com/loco-rs/loco/pull/969
- Added automatic updating of
updated_aton change https://github.com/loco-rs/loco/pull/962 - fixed codegen injection point in migrations https://github.com/loco-rs/loco/pull/952
NOTE: update your migration listing module like so:
// migrations/src/lib.rs
vec![
Box::new(m20220101_000001_users::Migration),
Box::new(m20231103_114510_notes::Migration),
Box::new(m20240416_071825_roles::Migration),
Box::new(m20240416_082115_users_roles::Migration),
// inject-above (do not remove this comment)
]
Add the comment just before the closing array (inject-above)
- Added ability to name references in https://github.com/loco-rs/loco/pull/955:
$ generate scaffold posts title:string! content:string! written_by:references:users approved_by:references:users
- Added hot-reload like experience to Tera templates https://github.com/loco-rs/loco/issues/977, in debug builds only.
NOTE: update your initializers after_routes like so:
// src/initializers/view_engine.rs
async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
#[allow(unused_mut)]
let mut tera_engine = engines::TeraView::build()?;
if std::path::Path::new(I18N_DIR).exists() {
let arc = ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US"))
.shared_resources(Some(&[I18N_SHARED.into()]))
.customize(|bundle| bundle.set_use_isolating(false))
.build()
.map_err(|e| Error::string(&e.to_string()))?;
#[cfg(debug_assertions)]
tera_engine
.tera
.lock()
.expect("lock")
.register_function("t", FluentLoader::new(arc));
#[cfg(not(debug_assertions))]
tera_engine
.tera
.register_function("t", FluentLoader::new(arc));
info!("locales loaded");
}
Ok(router.layer(Extension(ViewEngine::from(tera_engine))))
}
loco doctornow checks for app-specific minimum dependency versions. This should help in upgrades.doctoralso supports "production only" checks which you can run in production withloco doctor --production. This, for example, will check your connections but will not check dependencies. https://github.com/loco-rs/loco/pull/931- Use a single loco-rs dep for a whole project. https://github.com/loco-rs/loco/pull/927
- chore: fix generated testcase. https://github.com/loco-rs/loco/pull/939
- chore: Correct cargo test message. https://github.com/loco-rs/loco/pull/938
- Add relevant meta tags for better defaults. https://github.com/loco-rs/loco/pull/943
- Update cli message with correct command. https://github.com/loco-rs/loco/pull/942
- remove lazy_static. https://github.com/loco-rs/loco/pull/941
- change update HTTP verb semantics to put+patch. https://github.com/loco-rs/loco/pull/919
- Fixed HTML scaffold error. https://github.com/loco-rs/loco/pull/960
- Scaffolded HTML update method should be POST. https://github.com/loco-rs/loco/pull/963
v0.12.0
This release have been primarily about cleanups and simplification.
Please update:
loco-rsloco-cli
Changes:
- generators (BREAKING): all prefixes in starters (e.g.
/api) are now local to each controller, and generators will be prefix-aware (--apigenerator will add an/apiprefix to controllers) https://github.com/loco-rs/loco/pull/818
To migrate, please move prefixes from app.rs to each controller you use in controllers/, for example in notes controller:
Routes::new()
.prefix("api/notes")
.add("/", get(list))
-
starters: removed
.devcontainerwhich can now be found in loco-devcontainer -
starters: removed example
notesscaffold (model, controllers, etc), and unifieduserandauthinto a single file:auth.rs -
generators:
scaffoldgenerator will now generate a CRUD withPUTandPATCHsemantics for updating an entity https://github.com/loco-rs/loco/issues/896 -
cleanup:
loco-extraswas moved out of the repo, but we've incorporatedMultiDBandExtraDBfromextrasintoloco-rshttps://github.com/loco-rs/loco/pull/917 -
cargo loco doctornow checks for minimal required SeaORM CLI version -
BREAKING Improved migration generator. If you have an existing migration project, add the following comment indicator to the top of the
vecstatement and right below the opening bracked like so inmigration/src/lib.rs:
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
vec![
// inject-below (do not remove this comment)
v0.11.0
- Upgrade SeaORM to v1.1.0
- Added OpenAPI example
- Improve health route https://github.com/loco-rs/loco/pull/851
- Add good pragmas to Sqlite https://github.com/loco-rs/loco/pull/848
- Upgrade to rsbuild 1.0. https://github.com/loco-rs/loco/pull/792
- Implements fmt::Debug to pub structs. https://github.com/loco-rs/loco/pull/812
- Add num_workers config for sidekiq queue. https://github.com/loco-rs/loco/pull/823
- Fix some comments in the starters and example code. https://github.com/loco-rs/loco/pull/824
- Fix Y2038 bug for JWT on 32 bit platforms. https://github.com/loco-rs/loco/pull/825
- Make App URL in Boot Banner Clickable. https://github.com/loco-rs/loco/pull/826
- Add
--no-bannerflag to allow disabling the banner display. https://github.com/loco-rs/loco/pull/839 - add on_shutdown hook. https://github.com/loco-rs/loco/pull/842
v0.10.1
Format(respond_to): Formatextractor in controller can now be replaced withrespond_to: RespondToextractor for less typing.- When supplying data to views, you can now use
data!instead ofserde_json::json!for shorthand. - Refactor middlewares. https://github.com/loco-rs/loco/pull/785. Middleware selection, configuration, and tweaking is MUCH more powerful and convenient now. You can keep the
middleware:section empty or remove it now, see more in the middleware docs - NEW (BREAKING) background worker subsystem is now queue agnostic. Providing for both Redis and Postgres with a change of configuration. This means you can now use a full-Postgres stack to remove Redis as a dependency if you wish. Here are steps to migrate your codebase:
// in your app.rs, change the worker registration code:
// BEFORE
fn connect_workers<'a>(p: &'a mut Processor, ctx: &'a AppContext) {
p.register(DownloadWorker::build(ctx));
}
// AFTER
async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()>{
queue.register(DownloadWorker::build(ctx)).await?;
Ok(())
}
// in your app.rs, replace the `worker` module references.
// REMOVE
worker::{AppWorker, Processor},
// REPLACE WITH
bgworker::{BackgroundWorker, Queue},
// in your workers change the signature, and add the `build` function
// BEFORE
impl worker::Worker<DownloadWorkerArgs> for DownloadWorker {
async fn perform(&self, args: DownloadWorkerArgs) -> worker::Result<()> {
// AFTER
#[async_trait]
impl BackgroundWorker<DownloadWorkerArgs> for DownloadWorker {
fn build(ctx: &AppContext) -> Self {
Self { ctx: ctx.clone() }
}
async fn perform(&self, args: DownloadWorkerArgs) -> Result<()> {
// Finally, remove the `AppWorker` trait implementation completely.
// REMOVE
impl worker::AppWorker<DownloadWorkerArgs> for DownloadWorker {
fn build(ctx: &AppContext) -> Self {
Self { ctx: ctx.clone() }
}
}
Finally, update your development.yaml and test.yaml with a kind:
queue:
kind: Redis # add this to the existing `queue` section
- UPGRADED (BREAKING):
validatorcrate was upgraded which require some small tweaks to work with the new API:
// BEFORE:
#[validate(custom = "validation::is_valid_email")]
pub email: String,
// AFTER:
#[validate(custom (function = "validation::is_valid_email"))]
pub email: String,
Then update your Cargo.toml to take version 0.18:
# update
validator = { version = "0.18" }
- UPGRADED (BREAKING):
axum-testcrate was upgraded Update yourCargo.tomlto version16:
# update
axum-test = { version = "16" }
v0.9.0
- Add fallback behavior. https://github.com/loco-rs/loco/pull/732
- Add Scheduler Feature for Running Cron Jobs. https://github.com/loco-rs/loco/pull/735
- Add
--html,--htmxand--apiflags to scaffold CLI command. https://github.com/loco-rs/loco/pull/749 - Add base template for scaffold generation. https://github.com/loco-rs/loco/pull/752
- Connect Redis only when the worker is BackgroundQueue. https://github.com/loco-rs/loco/pull/755
- Add loco doctor --config. https://github.com/loco-rs/loco/pull/736
- Rename demo: blo -> demo_app. https://github.com/loco-rs/loco/pull/741
v0.8.1
- fix: introduce secondary binary for compile-and-run on Windows. https://github.com/loco-rs/loco/pull/727
v0.8.0
- Added: loco-cli (
loco new) now receives options from CLI and/or interactively asks for configuration options such as which asset pipeline, background worker type, or database provider to use. - Fix: custom queue names now merge with default queues.
- Added
remote_ipmiddleware for resolving client remote IP when under a proxy or loadbalancer, similar to the Railsremote_ipmiddleware. - Added
secure_headersmiddleware for setting secure headers by default, similar to how https://github.com/github/secure_headers works. This is now ON by default to promote security-by-default. - Added:
money,blobtypes to entitie generator.
0.7.0
- Moving to timezone aware timestamps. From now on migrations will generate timestamps with time zone by default. Moving to TZ aware timestamps in combination with newly revamped timestamp code generation in SeaORM v1.0.0 finally allows for seamlessly moving between using
sqliteandpostgreswith minimal or no entities code changes (resolved this long standing issue). TZ aware timestamps also aligns us with how Rails works today (initially Rails had a no-tz timestamps, and today the default is to use timestamps). If not specified the TZ is the server TZ, which is usually UTC, therefore semantically this is almost like a no-tz timestamp.
A few highlights:
Generated entities will now always use DateTimeWithTimeZone for the default timestamp fields:
...
Generating users.rs
> Column `created_at`: DateTimeWithTimeZone, not_null
> Column `updated_at`: DateTimeWithTimeZone, not_null
...
For better cross database provider compatibility, from now on prefer the tstz type instead of just ts when using generators (i.e. cargo loco generate model movie released:tstz)
-
remove eyer lib. https://github.com/loco-rs/loco/pull/650
Breaking Changes:
-
Update the Main Function in src/bin/main
Replace the return type of the main function:
Before:
async fn main() -> eyre::Result<()>After:
async fn main() -> loco_rs::Result<()> -
Modify examples/playground.rs You need to apply two changes here:
a. Update the Function Signature **Before:** ```rust async fn main() -> eyre::Result<()> ``` **After:** ```rust async fn main() -> loco_rs::Result<()> ``` b. Adjust the Context Handling **Before:** ```rust let _ctx = playground::<App>().await.context("playground")?; ``` **After:** ```rust let _ctx = playground::<App>().await?; ```Note, If you are using eyre in your project, you can continue to do so. We have only removed this crate from our base code dependencies.
-
-
Bump rstest crate to 0.21.0. https://github.com/loco-rs/loco/pull/650
-
Bump serial_test crate to 3.1.1. https://github.com/loco-rs/loco/pull/651
-
Bumo object store to create to 0.10.2. https://github.com/loco-rs/loco/pull/654
-
Bump axum crate to 0.7.5. https://github.com/loco-rs/loco/pull/652
-
Add Hooks::before_routes to give user control over initial axum::Router construction. https://github.com/loco-rs/loco/pull/646
-
Support logger file appender. https://github.com/loco-rs/loco/pull/636
-
Response from the template. https://github.com/loco-rs/loco/pull/682
-
Add get_or_insert function to cache layer. https://github.com/loco-rs/loco/pull/637
-
Bump ORM create to 1.0.0. https://github.com/loco-rs/loco/pull/684
0.6.2
- Use Rust-based tooling for SaaS starter frontend. https://github.com/loco-rs/loco/pull/625
- Default binding to localhost to avoid firewall dialogues during development on macOS. https://github.com/loco-rs/loco/pull/627
- upgrade sea-orm to 1.0.0 RC 7. https://github.com/loco-rs/loco/pull/627
- Add a down migration command. https://github.com/loco-rs/loco/pull/414
- replace create_postgres_database function table_name to db_name. https://github.com/loco-rs/loco/pull/647
0.6.1
- Upgrade htmx generator to htmx2. https://github.com/loco-rs/loco/pull/629
0.6.0 https://github.com/loco-rs/loco/pull/610
- Bump socketioxide to v0.13.1. https://github.com/loco-rs/loco/pull/594
- Add CC and BCC fields to the mailers. https://github.com/loco-rs/loco/pull/599
- Delete reset tokens after use. https://github.com/loco-rs/loco/pull/602
- Generator html support delete entity. https://github.com/loco-rs/loco/pull/604
- Breaking changes move task args from BTreeMap to struct. https://github.com/loco-rs/loco/pull/609
- Change task signature from
async fn run(&self, app_context: &AppContext, vars: &BTreeMap<String, String>)toasync fn run(&self, _app_context: &AppContext, _vars: &task::Vars) -> Result<()> - Breaking changes change default port to 5150. https://github.com/loco-rs/loco/pull/611
- Change task signature from
- Update shuttle version in deployment generation. https://github.com/loco-rs/loco/pull/616
v0.5.0 https://github.com/loco-rs/loco/pull/593
- refactor auth middleware for supporting bearer, cookie and query. https://github.com/loco-rs/loco/pull/560
- SeaORM upgraded:
rc1->rc4. https://github.com/loco-rs/loco/pull/585 - Adding Cache to app content. https://github.com/loco-rs/loco/pull/570
- Apply a layer to a specific handler using
layermethod. https://github.com/loco-rs/loco/pull/554 - Add the debug macro to the templates to improve the errors. https://github.com/loco-rs/loco/pull/547
- Opentelemetry initializer. https://github.com/loco-rs/loco/pull/531
- Refactor auth middleware for supporting bearer, cookie and query https://github.com/loco-rs/loco/pull/560
- Add redirect response https://github.com/loco-rs/loco/pull/563
- Breaking changes Adding a custom claims
Option<serde_json::Value>to theUserClaimsstruct (type changed). https://github.com/loco-rs/loco/pull/578 - Breaking changes Refactored DSL and Pagination: namespace changes. https://github.com/loco-rs/loco/pull/566
- Replaced
model::query::dsl::withmodel::query. - Replaced
model::query::exec::paginatewithmodel::query::paginate. - Updated the
PaginatedResponsestruct. Refer to its usage example here.
- Replaced
- Breaking changes When introducing the Cache system which is much more flexible than having just Redis, we now call the 'redis' member simply a 'queue' which indicates it should be used only for the internal queue and not as a general purpose cache. In the application configuration setting
redis, change toqueue. https://github.com/loco-rs/loco/pull/590
# before:
redis:
# after:
queue:
- Breaking changes We have made a few parts of the context pluggable, such as the
storageand newcachesubsystems, this is why we decided to let you configure the context entirely before starting up your app. As a result, if you have a storage building hook code it should move toafter_context, see example here. https://github.com/loco-rs/loco/pull/570
v0.4.0
- Refactored model validation for better developer experience. Added a few traits and structs to
loco::preludefor a smoother import story. IntroducingValidatable:
impl Validatable for super::_entities::users::ActiveModel {
fn validator(&self) -> Box<dyn Validate> {
Box::new(Validator {
name: self.name.as_ref().to_owned(),
email: self.email.as_ref().to_owned(),
})
}
}
// now you can call `user.validate()` freely
-
Refactored type field mapping to be centralized. Now model, scaffold share the same field mapping, so no more gaps like https://github.com/loco-rs/loco/issues/513 (e.g. when calling
loco generate model title:stringthe ability to mapstringinto something useful in the code generation side) NOTE the_integerclass of types are now just_int, e.g.big_int, so that it correlate with theintfield name in a better way -
Adding to to quiery dsl
is_inandis_not_in. https://github.com/loco-rs/loco/pull/507 -
Added: in your configuration you can now use an
initializers:section for initializer specific settings# Initializers Configuration initializers: # oauth2: # authorization_code: # Authorization code grant type # - client_identifier: google # Identifier for the OAuth2 provider. Replace 'google' with your provider's name if different, must be unique within the oauth2 config. # ... other fields -
Docs: fix schema data types mapping. https://github.com/loco-rs/loco/pull/506
-
Let Result accept other errors. https://github.com/loco-rs/loco/pull/505
-
Allow trailing slashes in URIs by adding the NormalizePathLayer. https://github.com/loco-rs/loco/pull/481
-
BREAKING Move from
Result<impl IntoResponse>toResult<Response>. This enables much greater flexibility building APIs, where withResult<Response>you mix and match response types based on custom logic (returning JSON and HTML/String in the same route). -
Added: mime responders similar to
respond_toin Rails:
- Use the
Formatextractor - Match on
respond_to - Create different content for different response formats
The following route will always return JSON, unless explicitly asked for HTML with a
Content-Type: text/html (or Accept: ) header:
pub async fn get_one(
Format(respond_to): Format,
Path(id): Path<i32>,
State(ctx): State<AppContext>,
) -> Result<Response> {
let item = load_item(&ctx, id).await?;
match respond_to {
RespondTo::Html => format::html(&format!("<html><body>{:?}</body></html>", item.title)),
_ => format::json(item),
}
}
0.3.2
- Redisgin pagination. https://github.com/loco-rs/loco/pull/463
- Wrap seaorm query and condition for common use cases. https://github.com/loco-rs/loco/pull/463
- Adding to loco-extras initializer for extra or multiple db. https://github.com/loco-rs/loco/pull/471
- Scaffold now supporting different templates such as API,HTML or htmx, this future is in beta.https://github.com/loco-rs/loco/pull/474
- Fix generatore fields types + adding tests. https://github.com/loco-rs/loco/pull/459
- Fix channel cors. https://github.com/loco-rs/loco/pull/430
- Improve auth controller compatibility with frontend https://github.com/loco-rs/loco/pull/472
0.3.1
- Breaking changes Upgrade sea-orm to v1.0.0-rc.1. https://github.com/loco-rs/loco/pull/420
Needs to update
sea-ormcrate to usev1.0.0-rc.1version. - Implemented file upload support with versatile strategies. https://github.com/loco-rs/loco/pull/423
- Create a
loco_extracrate to share common basic implementations. https://github.com/loco-rs/loco/pull/425 - Update shuttle deployment template to 0.38. https://github.com/loco-rs/loco/pull/422
- Enhancement: Move the Serve to Hook flow with the ability to override default serve settings. https://github.com/loco-rs/loco/pull/418
- Avoid cloning sea_query::ColumnDef. https://github.com/loco-rs/loco/pull/415
- Allow required UUID type in a scaffold. https://github.com/loco-rs/loco/pull/408
- Cover
SqlxMySqlPoolConnectionin db.rs. https://github.com/loco-rs/loco/pull/411 - Update worker docs and change default worker mode. https://github.com/loco-rs/loco/pull/412
- Added server-side view generation through a new
ViewEngineinfrastructure andTeraserver-side templates: https://github.com/loco-rs/loco/pull/389 - Added
generate model --migration-onlyhttps://github.com/loco-rs/loco/issues/400 - Add JSON to scaffold gen. https://github.com/loco-rs/loco/pull/396
- Add --binding(-b) and --port(-b) to
cargo loco start.https://github.com/loco-rs/loco/pull/402
0.2.3
- Add: support for pre-compressed assets.
- Added: Support socket channels, see working example here. https://github.com/loco-rs/loco/pull/380
- refactor: optimize checking permissions on Postgres. 9416c
- Added: E2E db. https://github.com/loco-rs/loco/pull/371
v0.2.2
v0.2.1
- enable compression for CompressionLayer, not etag. https://github.com/loco-rs/loco/pull/356
- Fix nullable JSONB column schema definition. https://github.com/loco-rs/loco/pull/357
v0.2.0
- Add: Loco now has Initializers (see the docs). Initializers help you integrate infra into your app in a seamless way, as well as share pieces of setup code between your projects
- Add: an
init_loggerhook insrc/app.rsfor those who want to take ownership of their logging and tracing stack. - Add: Return a JSON schema when payload json could not serialize to a struct. https://github.com/loco-rs/loco/pull/343
- Init logger in cli.rs. https://github.com/loco-rs/loco/pull/338
- Add: return JSON schema in panic HTTP layer. https://github.com/loco-rs/loco/pull/336
- Add: JSON field support in model generation. https://github.com/loco-rs/loco/pull/327 https://github.com/loco-rs/loco/pull/332
- Add: float support in model generation. https://github.com/loco-rs/loco/pull/317
- Fix: conflicting idx definition on M:M migration. https://github.com/loco-rs/loco/issues/311
- Add: Breaking changes Supply
AppContexttoroutesHook. Migration steps insrc/app.rs:
// src/app.rs: add app context to routes function
impl Hooks for App {
...
fn routes(_ctx: &AppContext) -> AppRoutes;
...
}
- Add: Breaking changes change parameter type from
&strto&Environmentinsrc/app.rs
// src/app.rs: change parameter type for `environment` from `&str` to `&Environment`
impl Hooks for App {
...
async fn boot(mode: StartMode, environment: &Environment) -> Result<BootResult> {
create_app::<Self>(mode, environment).await
}
...
- Added: setting cookies:
format::render()
.cookies(&[
cookie::Cookie::new("foo", "bar"),
cookie::Cookie::new("baz", "qux"),
])?
.etag("foobar")?
.json(notes)
v0.1.9
- Adding pagination on Models. https://github.com/loco-rs/loco/pull/238
- Adding compression middleware. https://github.com/loco-rs/loco/pull/205 Added support for compression middleware. usage:
middlewares:
compression:
enable: true
- Create a new Database from the CLI. https://github.com/loco-rs/loco/pull/223
- Validate if seaorm CLI is installed before running
cargo loco db entitiesand show a better error to the user. https://github.com/loco-rs/loco/pull/212 - Adding to
saas andrest-api` starters a redis and DB in GitHub action workflow to allow users work with github action out of the box. https://github.com/loco-rs/loco/pull/215 - Adding the app name and the environment to the DB name when creating a new starter. https://github.com/loco-rs/loco/pull/216
- Fix generator when users adding a
created_atorupdate_atfields. https://github.com/loco-rs/loco/pull/214 - Add:
format::renderwhich allows a builder-like formatting, including setting etag and ad-hoc headers - Add: Etag middleware, enabled by default in starter projects. Once you set an Etag it will check for cache headers and return
304if needed. To enable etag in your existing project:
#...
middlewares:
etag:
enable: true
usage:
format::render()
.etag("foobar")?
.json(Entity::find().all(&ctx.db).await?)
Authentication: Added API Token Authentication!
-
See https://github.com/loco-rs/loco/pull/217 Now when you generate a
saas starterorrest apistarter you will get additional authentication methods for free: -
Added: authentication added -- api authentication where each user has an API token in the schema, and you can authenticate with
Beareragainst that user. -
Added: authentication added --
JWTWithUserextractor, which is a convenience for resolving the authenticated JWT claims into a current user from database
migrating an existing codebase
Add the following to your generated src/models/user.rs:
#[async_trait]
impl Authenticable for super::_entities::users::Model {
async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self> {
let user = users::Entity::find()
.filter(users::Column::ApiKey.eq(api_key))
.one(db)
.await?;
user.ok_or_else(|| ModelError::EntityNotFound)
}
async fn find_by_claims_key(db: &DatabaseConnection, claims_key: &str) -> ModelResult<Self> {
super::_entities::users::Model::find_by_pid(db, claims_key).await
}
}
Update imports in this file to include model::Authenticable:
use loco_rs::{
auth, hash,
model::{Authenticable, ModelError, ModelResult},
validation,
validator::Validate,
};
v0.1.8
- Added:
loco versionfor getting an operable version string containing logical crate version and git SHA if available:0.3.0 (<git sha>)
To migrate to this behavior from earlier versions, it requires adding the following to your app.rs app hooks:
fn app_version() -> String {
format!(
"{} ({})",
env!("CARGO_PKG_VERSION"),
option_env!("BUILD_SHA")
.or(option_env!("GITHUB_SHA"))
.unwrap_or("dev")
)
}
Reminder: loco --version will give you the current Loco framework which your app was built against and loco version gives you your app version.
- Added:
loco generate migrationfor adding ad-hoc migrations - Added: added support in model generator for many-to-many link table generation via
loco generate model --link - Docs: added Migration section, added relations documentation 1:M, M:M
- Adding .devcontainer to starter projects https://github.com/loco-rs/loco/issues/170
- Braking changes: Adding
Hooks::bootapplication. Migration steps:// Load boot::{create_app, BootResult, StartMode} from loco_rs lib // Load migration: use migration::Migrator; Only when using DB // Adding boot hook with the following code impl Hooks for App { ... async fn boot(mode: StartMode, environment: &str) -> Result<BootResult> { // With DB: create_app::<Self, Migrator>(mode, environment).await // Without DB: create_app::<Self>(mode, environment).await } ... }
v0.1.7
- Added pretty backtraces https://github.com/loco-rs/loco/issues/41
- adding tests for note requests https://github.com/loco-rs/loco/pull/156
- Define the min rust version the loco can run https://github.com/loco-rs/loco/pull/164
- Added
cargo loco doctorcli command for validate and diagnose configurations. https://github.com/loco-rs/loco/pull/145 - Added ability to specify
settings:in config files, which are available in context - Adding compilation mode in the banner. https://github.com/loco-rs/loco/pull/127
- Support shuttle deployment generator. https://github.com/loco-rs/loco/pull/124
- Adding a static asset middleware which allows to serve static folder/data. Enable this section in config. https://github.com/loco-rs/loco/pull/134
static: enable: true # ensure that both the folder.path and fallback file path are existence. must_exist: true folder: uri: "/assets" path: "frontend/dist" fallback: "frontend/dist/index.html" - fix:
loco generate requesttest template. https://github.com/loco-rs/loco/pull/133 - Improve docker deployment generator. https://github.com/loco-rs/loco/pull/131
v0.1.6
- refactor: local settings are now
<env>.local.yamland available for all environments, for example you can add a localtest.local.yamlanddevelopment.local.yaml - refactor: removed
config-rsand now doing config loading by ourselves. - fix: email template rendering will not escape URLs
- Config with variables: It is now possible to use tera templates in config YAML files
Example of pulling a port from environment:
server:
port: { { get_env(name="NODE_PORT", default=5150) } }
It is possible to use any tera templating constructs such as loops, conditionals, etc. inside YAML configuration files.
-
Mailer: expose
stubin non-test -
Hooks::before_runwith a default blank implementation. You can now code some custom loading of resources or other things before the app runs -
an LLM inference example, text generation in Rust, using an API (
examples/inference) -
Loco starters version & create release script https://github.com/loco-rs/loco/pull/110
-
Configure Cors middleware https://github.com/loco-rs/loco/pull/114
-
Hooks::after_routesInvoke this function after the Loco routers have been constructed. This function enables you to configure custom Axum logics, such as layers, that are compatible with Axum. https://github.com/loco-rs/loco/pull/114 -
Adding docker deployment generator https://github.com/loco-rs/loco/pull/119
DOCS:
- Remove duplicated docs in auth section
- FAQ docs: https://github.com/loco-rs/loco/pull/116
ENHANCEMENTS:
- Remove unused libs: https://github.com/loco-rs/loco/pull/106
- turn off default features in tokio https://github.com/loco-rs/loco/pull/118
0.1.5
NEW FEATURES
format:htmlhttps://github.com/loco-rs/loco/issues/74- Create a stateless HTML starter https://github.com/loco-rs/loco/pull/100
- Added worker generator + adding a way to test workers https://github.com/loco-rs/loco/pull/92
ENHANCEMENTS:
- CI: allows cargo cli run on fork prs https://github.com/loco-rs/loco/pull/96