|
1 | | -[JSON:API](http://jsonapi.org) is a specification for building APIs in JSON. |
2 | | - |
3 | | -# Client |
4 | | -Quick usage example: |
5 | | -```dart |
6 | | -import 'package:http/http.dart'; |
7 | | -import 'package:json_api/json_api.dart'; |
8 | | -
|
9 | | -void main() async { |
10 | | - final httpClient = Client(); |
11 | | - final jsonApiClient = JsonApiClient(httpClient); |
12 | | - final companiesUri = Uri.parse('http://localhost:8080/companies'); |
13 | | - final response = await jsonApiClient.fetchCollection(companiesUri); |
14 | | - httpClient.close(); |
15 | | - print('Status: ${response.status}'); |
16 | | - print('Headers: ${response.headers}'); |
17 | | -
|
18 | | - final resource = response.data.unwrap().first; |
19 | | -
|
20 | | - print('The collection page size is ${response.data.collection.length}'); |
21 | | - print('The first element is ${resource}'); |
22 | | - print('Attributes:'); |
23 | | - resource.attributes.forEach((k, v) => print('$k=$v')); |
24 | | - print('Relationships:'); |
25 | | - resource.toOne.forEach((k, v) => print('$k=$v')); |
26 | | - resource.toMany.forEach((k, v) => print('$k=$v')); |
27 | | -} |
28 | | -``` |
29 | | -To see this in action: |
30 | | - |
31 | | - 1. start the server: |
32 | | -``` |
33 | | -$ dart example/cars_server.dart |
34 | | -Listening on 127.0.0.1:8080 |
35 | | -``` |
36 | | -2. run the script: |
37 | | -``` |
38 | | -$ dart example/fetch_collection.dart |
39 | | -Status: 200 |
40 | | -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: *} |
41 | | -The collection page size is 1 |
42 | | -The first element is Resource(companies:1) |
43 | | -Attributes: |
44 | | -name=Tesla |
45 | | -nasdaq=null |
46 | | -updatedAt=2019-07-07T13:08:18.125737 |
47 | | -Relationships: |
48 | | -hq=Identifier(cities:2) |
49 | | -models=[Identifier(models:1), Identifier(models:2), Identifier(models:3), Identifier(models:4)] |
50 | | -``` |
51 | | - |
52 | | -The client provides a set of methods to deal with resources and relationships. |
53 | | -- Fetching |
54 | | - - [fetchCollection](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/fetchCollection.html) - resource collection, either primary or related |
55 | | - - [fetchResource](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/fetchResource.html) - a single resource, either primary or related |
56 | | - - [fetchRelationship](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/fetchRelationship.html) - a generic relationship (either to-one, to-many or even incomplete) |
57 | | - - [fetchToOne](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/fetchToOne.html) - a to-one relationship |
58 | | - - [fetchToMany](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/fetchToMany.html) - a to-many relationship |
59 | | -- Manipulating resources |
60 | | - - [createResource](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/createResource.html) - creates a new primary resource |
61 | | - - [updateResource](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/updateResource.html) - updates the existing resource by its type and id |
62 | | - - [deleteResource](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/deleteResource.html) - deletes the existing resource |
63 | | -- Manipulating relationships |
64 | | - - [replaceToOne](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/replaceToOne.html) - replaces the existing to-one relationship with a new resource identifier |
65 | | - - [deleteToOne](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/deleteToOne.html) - deletes the existing to-one relationship by setting the resource identifier to null |
66 | | - - [replaceToMany](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/replaceToMany.html) - replaces the existing to-many relationship with the given set of resource identifiers |
67 | | - - [addToMany](https://pub.dev/documentation/json_api/latest/client/JsonApiClient/addToMany.html) - adds the given identifiers to the existing to-many relationship |
68 | | - |
69 | | -These methods accept the target URI and the object to update (except for fetch and delete requests). |
70 | | -You can also pass an optional map of HTTP headers, e.g. for authentication. The return value |
71 | | -is a [Response] object. |
72 | | - |
73 | | -You can get the status of the [Response] from either [Response.status] or one of the following properties: |
74 | | -- [Response.isSuccessful] |
75 | | -- [Response.isFailed] |
76 | | -- [Response.isAsync] (see [Asynchronous Processing]) |
77 | | - |
78 | | -The Response also contains the raw [Response.status] and a map of HTTP headers. |
79 | | -Two headers used by JSON:API can be accessed directly for your convenience: |
80 | | -- [Response.location] holds the `Location` header used in creation requests |
81 | | -- [Response.contentLocation] holds the `Content-Location` header used for [Asynchronous Processing] |
82 | | - |
83 | | -The most important part of the Response is the [Response.document] containing the JSON:API document sent by the server (if any). |
84 | | -If the document has the Primary Data, you can use [Response.data] shortcut to access it directly. |
85 | | - |
86 | | -#### Included resources |
87 | | -If you requested related resources to be included in the response (see [Compound Documents]) and the server fulfilled |
88 | | -your request, the [PrimaryData.included] property will contain them. |
89 | | - |
90 | | -#### Errors |
91 | | -For unsuccessful operations the [Response.data] property will be null. |
92 | | -If the server decided to include the error details in the response, those can be found in the [Document.errors] property. |
93 | | - |
94 | | -#### Async processing |
95 | | -Some servers may support [Asynchronous Processing]. |
96 | | -When the server responds with `202 Accepted`, the client expects the Primary Data to always be a Resource (usually |
97 | | -representing a job queue). In this case, [Response.document] and [Response.data] will be null. Instead, |
98 | | -the response document will be placed to [Response.asyncDocument] (and [Response.asyncData]). |
99 | | -Also in this case the [Response.contentLocation] |
100 | | -will point to the job queue resource. You can fetch the job queue resource periodically and check |
101 | | -the type of the returned resource. Once the operation is complete, the request will return the created resource. |
102 | | - |
103 | | -#### Adding JSON:API Object |
104 | | -It is possible to add the [JSON:API Object] to all documents sent by the [JsonApiClient]. To do so, pass the |
105 | | -pre-configured [DocumentFactory] to the [JsonApiClient]: |
106 | | -```dart |
107 | | -import 'package:http/http.dart'; |
108 | | -import 'package:json_api/json_api.dart'; |
109 | | -
|
110 | | -void main() async { |
111 | | - final api = Api(version: "1.0"); |
112 | | - final httpClient = Client(); |
113 | | - final jsonApiClient = JsonApiClient(httpClient, documentFactory: DocumentFactory(api: api)); |
114 | | -} |
115 | | -
|
116 | | -``` |
117 | | - |
118 | | - |
119 | | -# Server |
120 | | -The server included in this package is still under development. It is not yet suitable for real production environment |
121 | | -except maybe for really simple demo or testing cases. |
122 | | - |
123 | | -## URL Design |
124 | | -The URL Design specifies the structure of the URLs used for specific targets. The JSON:API standard describes 4 |
125 | | -possible request targets: |
126 | | -- Collections (parameterized by the resource type) |
127 | | -- Individual resources (parameterized by the resource type and id) |
128 | | -- Related resources and collections (parameterized by the resource type, resource id and the relation name) |
129 | | -- Relationships (parameterized by the resource type, resource id and the relation name) |
130 | | - |
131 | | -The [UrlFactory] makes those 4 kinds of URLs by the given parameters. The [TargetMatcher] does the opposite, |
132 | | -it determines the target of the given URL (if possible). Together they form the [UrlDesign]. |
133 | | - |
134 | | -This package provides one built-in implementation of [UrlDesign] which is called [PathBasedUrlDesign]. |
135 | | -The [PathBasedUrlDesign] implements the [Recommended URL Design] allowing you to specify the a common prefix |
136 | | -for all your JSON:API endpoints. |
137 | | - |
138 | | - |
139 | | -[DocumentFactory]: https://pub.dev/documentation/json_api/latest/document_factory/DocumentFactory-class.html |
140 | | -[Document.errors]: https://pub.dev/documentation/json_api/latest/document/Document/errors.html |
141 | | -[JsonApiClient]: https://pub.dev/documentation/json_api/latest/client/JsonApiClient-class.html |
142 | | -[PathBasedUrlDesign]: https://pub.dev/documentation/json_api/latest/url_design/PathBasedUrlDesign-class.html |
143 | | -[PrimaryData.included]: https://pub.dev/documentation/json_api/latest/document/PrimaryData/included.html |
144 | | -[Response]: https://pub.dev/documentation/json_api/latest/client/Response-class.html |
145 | | -[Response.data]: https://pub.dev/documentation/json_api/latest/client/Response/data.html |
146 | | -[Response.document]: https://pub.dev/documentation/json_api/latest/client/Response/document.html |
147 | | -[Response.isSuccessful]: https://pub.dev/documentation/json_api/latest/client/Response/isSuccessful.html |
148 | | -[Response.isFailed]: https://pub.dev/documentation/json_api/latest/client/Response/isFailed.html |
149 | | -[Response.isAsync]: https://pub.dev/documentation/json_api/latest/client/Response/isAsync.html |
150 | | -[Response.location]: https://pub.dev/documentation/json_api/latest/client/Response/location.html |
151 | | -[Response.contentLocation]: https://pub.dev/documentation/json_api/latest/client/Response/contentLocation.html |
152 | | -[Response.status]: https://pub.dev/documentation/json_api/latest/client/Response/status.html |
153 | | -[Response.asyncDocument]: https://pub.dev/documentation/json_api/latest/client/Response/asyncDocument.html |
154 | | -[Response.asyncData]: https://pub.dev/documentation/json_api/latest/client/Response/asyncData.html |
155 | | -[TargetMatcher]: https://pub.dev/documentation/json_api/latest/url_design/TargetMatcher-class.html |
156 | | -[UrlFactory]: https://pub.dev/documentation/json_api/latest/url_design/UrlFactory-class.html |
157 | | -[UrlDesign]: https://pub.dev/documentation/json_api/latest/url_design/UrlDesign-class.html |
158 | | - |
159 | | -[Asynchronous Processing]: https://jsonapi.org/recommendations/#asynchronous-processing |
160 | | -[Compound Documents]: https://jsonapi.org/format/#document-compound-documents |
161 | | -[JSON:API Object]: https://jsonapi.org/format/#document-jsonapi-object |
162 | | -[Recommended URL Design]: https://jsonapi.org/recommendations/#urls |
| 1 | +[JSON:API](http://jsonapi.org) is a specification for building APIs in JSON. |
| 2 | + |
| 3 | +This package consists of several libraries: |
| 4 | +- The [Client] to make requests to JSON:API servers |
| 5 | +- The [Server] which is still under development |
| 6 | +- The [Document] model for resources, relationships, identifiers, etc |
| 7 | +- The [Query] to build and parse the query parameters (pagination, sorting, etc) |
| 8 | +- The [URL Design] to build and match URLs for resources, collections, and relationships |
| 9 | + |
| 10 | +[Client]: https://pub.dev/documentation/json_api/latest/client/client-library.html |
| 11 | +[Server]: https://pub.dev/documentation/json_api/latest/server/server-library.html |
| 12 | +[Document]: https://pub.dev/documentation/json_api/latest/document/document-library.html |
| 13 | +[Query]: https://pub.dev/documentation/json_api/latest/query/query-library.html |
| 14 | +[URL Design]: https://pub.dev/documentation/json_api/latest/url_design/url_design-library.html |
0 commit comments