1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-30 18:34:36 +01:00

added Json response support

This commit is contained in:
Nikolay Kim 2017-12-03 18:51:52 -08:00
parent 5decff9154
commit 319e9bbd05
4 changed files with 67 additions and 4 deletions

View File

@ -23,7 +23,7 @@ fn main() {
## Directory
To serve all files from specific directory `StaticFiles` type could be used.
To serve files from specific directory and sub-directories `StaticFiles` type could be used.
`StaticFiles` could be registered with `Application::route` method.
```rust
@ -36,6 +36,6 @@ fn main() {
}
```
First parameter is a base directory. Second parameter is `show_index`, if it set to *true*
First parameter is a base directory. Second parameter is *show_index*, if it is set to *true*
directory listing would be returned for directories, if it is set to *false*
then *404 Not Found* would be returned instead of directory listing.

View File

@ -13,3 +13,29 @@ Following encodings are supported:
If request headers contains `Content-Encoding` header, request payload get decompressed
according to header value. Multiple codecs are not supported, i.e: `Content-Encoding: br, gzip`.
## JSON Response
The `Json` type allows you to respond with well-formed JSON data: simply return a value of
type Json<T> where T is the type of a structure to serialize into *JSON*. The
type `T` must implement the `Serialize` trait from *serde*.
```rust
extern crate actix_web;
#[macro_use] extern crate serde_derive;
use actix_web::*;
#[derive(Serialize)]
struct MyObj {
name: String,
}
fn index(req: HttpRequest) -> Result<Json<MyObj>> {
Ok(Json(MyObj{name: req.match_info().query("name")?}))
}
fn main() {
Application::default("/")
.resource(r"/a/{name}", |r| r.get(index))
.finish();
}
```

View File

@ -34,7 +34,8 @@ extern crate percent_encoding;
extern crate actix;
extern crate h2 as http2;
// extern crate redis_async;
#[cfg(test)]
#[macro_use] extern crate serde_derive;
#[cfg(feature="tls")]
extern crate native_tls;
@ -81,7 +82,7 @@ pub use application::Application;
pub use httprequest::{HttpRequest, UrlEncoded};
pub use httpresponse::HttpResponse;
pub use payload::{Payload, PayloadItem};
pub use route::{Reply, FromRequest};
pub use route::{Reply, Json, FromRequest};
pub use resource::Resource;
pub use recognizer::Params;
pub use server::HttpServer;

View File

@ -2,6 +2,8 @@ use std::marker::PhantomData;
use actix::Actor;
use futures::Future;
use serde_json;
use serde::Serialize;
use error::Error;
use context::{HttpContext, IoContext};
@ -223,3 +225,37 @@ impl<S, R, F> RouteHandler<S> for AsyncHandler<S, R, F>
Reply::async((self.f)(req))
}
}
pub struct Json<T: Serialize> (pub T);
impl<T: Serialize> FromRequest for Json<T> {
type Item = HttpResponse;
type Error = Error;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, Error> {
let body = serde_json::to_string(&self.0)?;
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(body)?)
}
}
#[cfg(test)]
mod tests {
use super::*;
use http::header;
#[derive(Serialize)]
struct MyObj {
name: &'static str,
}
#[test]
fn test_json() {
let json = Json(MyObj{name: "test"});
let resp = json.from_request(HttpRequest::default()).unwrap();
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), "application/json");
}
}