Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.6.0] - 2019-03-25
### Changed
- JSON:API Document moved out
- Renamed `client.removeToOne` to `client.deleteToOne`

## [0.5.0] - 2019-03-21
### Changed
- More BC-breaking changes in the Server
Expand Down Expand Up @@ -47,7 +52,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Client: fetch resources, collections, related resources and relationships

[Unreleased]: https://github.com/f3ath/json-api-dart/compare/0.5.0...HEAD
[Unreleased]: https://github.com/f3ath/json-api-dart/compare/0.6.0...HEAD
[0.6.0]: https://github.com/f3ath/json-api-dart/compare/0.5.0...0.6.0
[0.5.0]: https://github.com/f3ath/json-api-dart/compare/0.4.0...0.5.0
[0.4.0]: https://github.com/f3ath/json-api-dart/compare/0.3.0...0.4.0
[0.3.0]: https://github.com/f3ath/json-api-dart/compare/0.2.0...0.3.0
Expand Down
75 changes: 62 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,83 @@
[JSON:API](http://jsonapi.org) is a specification for building APIs in JSON. This library implements
a Client (VM, Flutter, Web), and a Server (VM only).

## Supported features
- Fetching single resources and resource collections
## Features
- Fetching single resources, resource collections, related resources
- Fetching/updating relationships
- Creating/updating/deleting resources
- Collection pagination
- Fetching relationships and related resources and collections
- Fetching single resources
- Creating resources
- Deleting resources
- Updating resource's attributes
- Updating resource's relationships
- Updating relationships
- Compound documents
- Related collection pagination
- Asynchronous processing

## Usage
In the VM:
### Creating a client instance
JSON:API Client uses the Dart's native HttpClient. Depending on the platform,
you may want to use either the one which comes from `dart:io` or the `BrowserClient`.

In the VM/Flutter you don't need to provide any dependencies:
```dart
import 'package:json_api/client.dart';

final client = JsonApiClient();
```

In a browser:
In a browser use the `BrowserClient`:
```dart
import 'package:json_api/client.dart';
import 'package:http/browser_client.dart';

final client = JsonApiClient(factory: () => BrowserClient());
```

For usage examples see the [functional tests](https://github.com/f3ath/json-api-dart/tree/master/test/functional).
### Making requests
The client provides a set of methods to manipulate resources and relationships.
- Fetching
- `fetchCollection` - resource collection, either primary or related
- `fetchResource` - a single resource, either primary or related
- `fetchRelationship` - a generic relationship (either to-one, to-many or even incomplete)
- `fetchToOne` - a to-one relationship
- `fetchToMany` - a to-many relationship
- Manipulating resources
- `createResource` - creates a new primary resource
- `updateResource` - updates the existing resource by its type and id
- `deleteResource` - deletes the existing resource
- Manipulating relationships
- `replaceToOne` - replaces the existing to-one relationship with a new resource identifier
- `deleteToOne` - deletes the existing to-one relationship by setting the resrouce identifier to null
- `replaceToMany` - replaces the existing to-many relationship with the given set of resource identifiers
- `addToMany` - adds the given identifiers to the existing to-many relationship

These methods accept the target URI and the object to update (except for fetch and delete requests).
You can also pass an optional map of HTTP headers e.g. for authentication. The return value
is `Response` object bearing the HTTP response status and headers and the JSON:API
document with the primary data according to the type of the request.

Here's a collection fetching example:

```dart
import 'package:json_api/client.dart';

void main() async {
final client = JsonApiClient();
final companiesUri = Uri.parse('http://localhost:8080/companies');
final response = await client.fetchCollection(companiesUri);

print('Status: ${response.status}');
print('Headers: ${response.headers}');

print('The collection page size is ${response.data.collection.length}');

final resource = response.data.collection.first.toResource();
print('The first element is ${resource}');

print('Attributes:');
resource.attributes.forEach((k, v) => print('$k=$v'));

print('Relationships:');
resource.toOne.forEach((k, v) => print('$k=$v'));
resource.toMany.forEach((k, v) => print('$k=$v'));
}
```


For more usage examples refer to the [functional tests](https://github.com/f3ath/json-api-dart/tree/master/test/functional).
8 changes: 6 additions & 2 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ You can run it locally to play around.
- In you console run `dart example/cars_server.dart`, this will start the server at port 8080.
- Open http://localhost:8080/companies in the browser.

## [Cars Client](./cars_client.dart)
A simple client for Cars Server API. It is also used in the tests.
## [Fetch example](./fetch_collection.dart)
With the server running, call
```
dart example/fetch_collection.dart
```
This will make a `fetchCollection()` call and print the response.
19 changes: 19 additions & 0 deletions example/fetch_collection.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:json_api/client.dart';

void main() async {
final client = JsonApiClient();
final companiesUri = Uri.parse('http://localhost:8080/companies');
final response = await client.fetchCollection(companiesUri);
print('Status: ${response.status}');
print('Headers: ${response.headers}');

final resource = response.data.collection.first.toResource();

print('The collection page size is ${response.data.collection.length}');
print('The first element is ${resource}');
print('Attributes:');
resource.attributes.forEach((k, v) => print('$k=$v'));
print('Relationships:');
resource.toOne.forEach((k, v) => print('$k=$v'));
resource.toMany.forEach((k, v) => print('$k=$v'));
}
2 changes: 1 addition & 1 deletion lib/src/client/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class JsonApiClient {

/// Removes a to-one relationship. This is equivalent to calling [replaceToOne]
/// with id = null.
Future<Response<ToOne>> removeToOne(Uri uri, {Map<String, String> headers}) =>
Future<Response<ToOne>> deleteToOne(Uri uri, {Map<String, String> headers}) =>
replaceToOne(uri, null, headers: headers);

/// Replaces a to-many relationship with the given set of [ids].
Expand Down
1 change: 0 additions & 1 deletion test/browser_compat_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ void main() async {
final channel = spawnHybridUri('test_server.dart');
final client = JsonApiClient(factory: () => BrowserClient());
final port = await channel.stream.first;
print('Port: $port');
final r = await client
.fetchCollection(Uri.parse('http://localhost:$port/companies'));
expect(r.status, 200);
Expand Down
2 changes: 1 addition & 1 deletion test/functional/update_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ void main() async {
final original = r0.document.data.toIdentifier();
expect(original.id, '2');

final r1 = await client.removeToOne(url);
final r1 = await client.deleteToOne(url);
expect(r1.status, 204);

final r2 = await client.fetchToOne(url);
Expand Down