From c63ee84acbb7d7a9ecabb91ee4863c2e7397615e Mon Sep 17 00:00:00 2001 From: regiostech Date: Thu, 3 Mar 2016 23:30:13 -0500 Subject: [PATCH] Next comes array support. --- README.md | 72 ++++++++++++++++++++++++++++++- Test Results - Run_All_Tests.html | 69 ++++++++++++++++++++++------- lib/body_parser.dart | 3 +- test/all_tests.dart | 70 +++++++++++++++++++++++++++--- 4 files changed, 188 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index af780523..02b1cda1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,72 @@ -# body_parser +# Body Parser +![version 1.0.0-dev](https://img.shields.io/badge/version-1.0.0--dev-red.svg) + +**NOT YET PRODUCTION READY** + Parse request bodies and query strings in Dart. + +### Contents + +* [Body Parser](#body-parser) +* [About](#about) +* [Installation](#installation) +* [Usage](#usage) +* [Thanks](#thank-you-for-using-body_parser) + +# About + +I needed something like Express.js's `body-parser` module, so I made it here. It fully supports JSON requests. +x-www-form-urlencoded is partially supported, as well as query strings. By the next update, they will be fully supported. +The only missing link in the implementation is that I have not yet provided support for arrays in the query. File upload support +will also be present by the production 1.0.0 release. + +A benefit of this is that primitive types are automatically deserialized correctly. As in, if you have a `hello=1.5` request, then +`body['hello']` will equal `1.5` and not `'1.5'`. A very semantic difference, yes, but it relieves stress in my head. + +# Installation + +To install Body Parser for your Dart project, simply add body_parser to your +pub dependencies. + + dependencies: + body_parser: any + +# Usage + +Body Parser exposes a simple class called [BodyParseResult]. +You can easily parse the query string and request body for a request by calling `Future parseBody`. + +```dart +import 'dart:convert'; +import 'package:body_parser/body_parser.dart'; + +main() async { + // ... + await for (HttpRequest request in server) { + request.response.write(JSON.encode(await parseBody(request).body)); + await request.response.close(); + } +} +``` + +This can easily be used with a library like [JSON God](https://github.com/thosakwe/json_god) +to build structured JSON/REST APIs. Add validation and you've got an instant backend. + +```dart + +MyClass create(HttpRequest request) async { + God god = new God(); + return god.deserialize(await parseBody(request).body, MyClass); +} +``` + + +# Thank you for using Body Parser + +Thank you for using this library. I hope you like it. + +Feel free to follow me on Twitter: + +[@thosakwe](http://twitter.com/thosakwe) +or +[@regios_tech](http://twitter.com/regios_tech) \ No newline at end of file diff --git a/Test Results - Run_All_Tests.html b/Test Results - Run_All_Tests.html index 5eb5a1aa..1cac1124 100644 --- a/Test Results - Run_All_Tests.html +++ b/Test Results - Run_All_Tests.html @@ -572,8 +572,8 @@ jQuery.cookie = function(name, value, options) {
diff --git a/lib/body_parser.dart b/lib/body_parser.dart index cdb02558..5a0902f1 100644 --- a/lib/body_parser.dart +++ b/lib/body_parser.dart @@ -1,5 +1,4 @@ -// A library for parsing HTTP request bodies and queries. - +/// A library for parsing HTTP request bodies and queries. library body_parser; import 'dart:async'; diff --git a/test/all_tests.dart b/test/all_tests.dart index de173cd8..e56d95f2 100644 --- a/test/all_tests.dart +++ b/test/all_tests.dart @@ -33,15 +33,66 @@ main() { god = null; }); - group('JSON', () { - test('Post Simple JSON', () async { - var response = await client.post(url, body: { - 'hello': 'world' - }); + group('query string', () { + test('GET Simple', () async { + print('GET $url/?hello=world'); + var response = await client.get('$url/?hello=world'); + print('Response: ${response.body}'); + expect(response.body, equals('{"body":{},"query":{"hello":"world"}}')); + }); + + test('GET Complex', () async { + var postData = 'hello=world&nums[]=1&nums[]=2.0&nums[]=${3 - + 1}&map.foo.bar=baz'; + var response = await client.get('$url/?$postData'); + var body = god.deserialize(response.body)['body']; + expect(body['hello'], equals('world')); + expect(body['nums'][2], equals(2)); + expect(body['map'] is Map, equals(true)); + expect(body['map']['foo'], equals({'bar': 'baz'})); + }, skip: 'Array support via query string is pending.'); + }); + + group('urlencoded', () { + Map headers = { + HttpHeaders.CONTENT_TYPE: 'application/x-www-form-urlencoded' + }; + test('POST Simple', () async { + print('Body: hello=world'); + var response = await client.post( + url, headers: headers, body: 'hello=world'); + print('Response: ${response.body}'); expect(response.body, equals('{"body":{"hello":"world"},"query":{}}')); }); - test('Post Complex JSON', () async { + test('Post Complex', () async { + var postData = 'hello=world&nums[]=1&nums[]=2.0&nums[]=${3 - + 1}&map.foo.bar=baz'; + var response = await client.post(url, headers: headers, body: postData); + var body = god.deserialize(response.body)['body']; + expect(body['hello'], equals('world')); + expect(body['nums'][2], equals(2)); + expect(body['map'] is Map, equals(true)); + expect(body['map']['foo'], equals({'bar': 'baz'})); + }, skip: 'Array support via urlencoded is pending.'); + }); + + group('JSON', () { + Map headers = { + HttpHeaders.CONTENT_TYPE: ContentType.JSON.toString() + }; + test('Post Simple', () async { + var postData = god.serialize({ + 'hello': 'world' + }); + print('Body: $postData'); + var response = await client.post( + url, headers: headers, body: postData); + print('Response: ${response.body}'); + expect(response.body, equals('{"body":{"hello":"world"},"query":{}}')); + }); + + test('Post Complex', () async { var postData = god.serialize({ 'hello': 'world', 'nums': [1, 2.0, 3 - 1], @@ -51,9 +102,14 @@ main() { } } }); - var response = await client.post(url, body: postData); + print('Body: $postData'); + var response = await client.post(url, headers: headers, body: postData); + print('Response: ${response.body}'); var body = god.deserialize(response.body)['body']; expect(body['hello'], equals('world')); + expect(body['nums'][2], equals(2)); + expect(body['map'] is Map, equals(true)); + expect(body['map']['foo'], equals({'bar': 'baz'})); }); }); });