json_api 2.0.2

JSON:API is a specification for building APIs in JSON.

Client #

Quick usage example:

import 'package:http/http.dart';
import 'package:json_api/json_api.dart';

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

  final resource = response.data.unwrap().first;

  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'));
}

To see this in action:

  1. start the server:
$ dart example/cars_server.dart
Listening on 127.0.0.1:8080
  1. run the script:
$ dart example/fetch_collection.dart 
Status: 200
Headers: {x-frame-options: SAMEORIGIN, content-type: application/vnd.api+json, x-xss-protection: 1; mode=block, x-content-type-options: nosniff, transfer-encoding: chunked, access-control-allow-origin: *}
The collection page size is 1
The first element is Resource(companies:1)
Attributes:
name=Tesla
nasdaq=null
updatedAt=2019-07-07T13:08:18.125737
Relationships:
hq=Identifier(cities:2)
models=[Identifier(models:1), Identifier(models:2), Identifier(models:3), Identifier(models:4)]

The client provides a set of methods to deal with resources and relationships.

  • Fetching
  • Manipulating resources
  • Manipulating relationships
    • replaceToOne - replaces the existing to-one relationship with a new resource identifier
    • deleteToOne - deletes the existing to-one relationship by setting the resource 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 a Response object.

You can get the status of the Response from either Response.status or one of the following properties:

The Response also contains the raw Response.status and a map of HTTP headers. Two headers used by JSON:API can be accessed directly for your convenience:

The most important part of the Response is the Response.document containing the JSON:API document sent by the server (if any). If the document has the Primary Data, you can use Response.data shortcut to access it directly.

Included resources #

If you requested related resources to be included in the response (see Compound Documents) and the server fulfilled your request, the PrimaryData.included property will contain them.

Errors #

For unsuccessful operations the Response.data property will be null. If the server decided to include the error details in the response, those can be found in the Document.errors property.

Async processing #

Some servers may support Asynchronous Processing. When the server responds with 202 Accepted, the client expects the Primary Data to always be a Resource (usually representing a job queue). In this case, Response.document and Response.data will be null. Instead, the response document will be placed to Response.asyncDocument (and Response.asyncData). Also in this case the Response.contentLocation will point to the job queue resource. You can fetch the job queue resource periodically and check the type of the returned resource. Once the operation is complete, the request will return the created resource.

Server #

The server included in this package is still under development. It is not yet suitable for real production environment except maybe for really simple demo or testing cases.

URL Design #

The URL Design specifies the structure of the URLs used for specific targets. The JSON:API standard describes 4 possible request targets:

  • Collections (parameterized by the resource type)
  • Individual resources (parameterized by the resource type and id)
  • Related resources and collections (parameterized by the resource type, resource id and the relation name)
  • Relationships (parameterized by the resource type, resource id and the relation name)

The URLBuilder builds those 4 kinds of URLs by the given parameters. The TargetMatcher does the opposite, it determines the target of the given URL (if possible). Together they form the UrlDesign.

This package provides one built-in implementation of UrlDesign which is called PathBasedUrlDesign. The PathBasedUrlDesign implements the Recommended URL Design allowing you to specify the a common prefix for all your JSON:API endpoints.

Changelog #

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Unreleased #

2.0.2 - 2019-08-01

Fixed #

  • Meta members have incorrect type (#54)

2.0.1 - 2019-07-12

Fixed #

  • Readme example is outdated

2.0.0 - 2019-07-12

Changed #

  • This package now consolidates the Client, the Server and the Document in one single library. It does not depend on json_api_document and json_api_server anymore, please remove these packages from your pubspec.yaml.
  • The min Dart SDK version bumped to 2.3.0
  • The Client requires an instance of HttpClient to be passed to the constructor explicitly.
  • Both the Document and the Server have been refactored with lots of BREAKING CHANGES. See the examples and the functional tests for details.
  • Meta properties are not defensively copied, but set directly. Meta property behavior is unified across the Document model.

Removed #

  • JsonApiParser is removed. Use the static decodeJson methods in the corresponding classes instead.

1.0.1 - 2019-04-05

Fixed #

  • Bumped the dependencies versions due to a bug in json_api_document.

1.0.0 - 2019-03-20

Changed #

  • JSON:API Server moved out

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

Fixed #

  • Location headers were incorrectly generated by Server

Added #

  • Related collection pagination
  • Async operations support

0.4.0 - 2019-03-17

Changed #

  • Parsing logic moved out
  • Some other BC-breaking changes in the Document
  • Huge changes in the Server

Added #

  • Compound documents support in Client (Server-side support is still very limited)

Fixed #

  • Server was not setting links for resources and relationships

0.3.0 - 2019-03-16

Changed #

  • Huge BC-breaking refactoring in the Document model which propagated everywhere

Added #

  • Resource attributes update
  • Resource relationships update

0.2.0 - 2019-03-01

Added #

  • Improved ResourceController error handling
  • Resource creation
  • Resource deletion

0.1.0 - 2019-02-27 #

Added #

  • Client: fetch resources, collections, related resources and relationships

example/README.md

JSON:API examples #

Cars Server #

This is a simple JSON:API server which is used in the tests. It provides an API to a collection to car companies and models. You can run it locally to play around.

Fetch example #

With the server running, call

dart example/fetch_collection.dart

This will make a fetchCollection() call and print the response.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  json_api: ^2.0.2

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:json_api/json_api.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
73
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
87
Learn more about scoring.

We analyzed this package on Sep 19, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.0
  • pana: 0.12.21

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:json_api/json_api.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.3.0 <3.0.0
collection ^1.14.11 1.14.12
http ^0.12.0 0.12.0+2
Transitive dependencies
async 2.3.0
charcode 1.1.2
http_parser 3.1.3
meta 1.1.7
path 1.6.4
pedantic 1.8.0+1
source_span 1.5.5
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
Dev dependencies
json_matcher ^0.2.3
stream_channel ^1.6.8
test ^1.6.1
uuid ^2.0.1