Old iron remember to forward, Brother Mao will present more Flutter good articles~~~~
WeChat group ducafecat
b station https://space.bilibili.com/404904528
original
https://medium.com/teamkraken/converting-json-api-response-to-dart-objects-with-chopper-and-jsonserializable-8ec98b762ac1
Code
https://github.com/ErkinKurt/chopper_json_serializable
reference
- https://hadrien-lejard.gitbook.io/chopper/
- https://github.com/infinum/Japx
- https://jsonapi.org/
- https://github.com/dart-lang/build
text
However, the JSON response format differs from service to service; there are some shared conventions, such as JSON: API, HAL... Today, I will try to show how to start from scratch and convert JSON: API responses into Dart objects in a Flutter project.
If you want to follow the source code, here is: Chopper json serializable
https://github.com/ErkinKurt/chopper_json_serializable
1. Create a project and add dependencies
Packages to be used:
- Chopper:
Dart and Flutter Http client generators using source gen and Retrofit - Json Serializable:
By using it, JSON conversion of entities will be automatically generated - Japx:
Parser, which turns complex JSON: API structure into simple JSON, and vice versa
Thank you so much for these awesome packages!
Since JsonSerializable and Chopper use meta programming, they need BuildRunner to handle code generation. Here is the pubspec.yaml file to be used:
2. Implement Mock Http Client to get the response in JSON: API format
The response model is provided in the assets folder because we want to use a mock http client and do not rely on any remote sources. The response model is taken from JAPX assets.
If you want to use chopper with regular http client just ignore this part and follow the following part...
3. Create a model and use JsonSerializable
Although for the sake of simplicity, we have two entities, Article and People, but they will inherit from the Entity class to demonstrate how to use JsonSerializable with inheritance. Because every entity has a type and id value in JSON: API, we created a base class with type and id.
abstract class Entity {
final String type;
final String id;
Entity(this.type, this.id);
}
Let us implement two models with JsonSerializable. We need to write part'<model-name>. At the end of the day, the json and FromJson constructors will be generated by the runner built in this directory.
We are defining fromJsonFactory to be used in JsonTypeConvertor, and we will see its use later.
After completing our implementation, we need to run flutter pub run build runner build in the root directory of the project, so that the build runner can perform its magic. After successful execution, we see. The G file is generated without errors.
4. Create Chopper Service
Let's create the network layer and Chopper service. Chopper Services uses automatic generation to create the underlying http client implementation, so we don't need to worry about http client requests.
We provide a static creation method to inject services into ChopperClients. In addition, we also have getArticle and getPerson methods to get a single entity through the http client.
As you can see, we have some red lights on. This is because chopper uses code generation with the help of (build runner the underlying hero).
Let us run the flutter pub run build \_ runner build command as before. If the execution is successful, we will not see any errors. Please take a look at the generated code to see how chopper handles basic http client requests.
5. Implement Chopper Client
Now we need to implement the Chopper client to use the Chopper service we created. Chopper Client provides service properties and sets up multiple services. For client use, there are two options, either create a client as a singleton and deliver all services, or create a client whenever needed.
For this example, let's create a chopper client instance and pass it to the widget tree. However, we can use getIt or provider as dependency injection. For the sake of simplicity, we will use it as a pillar.
Below is a ChopperClientBuilder, which provides a method to build our ChopperClientBuilder client.
6. Use the JAPX decoder in the user interface to use the Chopper service
We have a stateful widget with chopper client as a prop. We will implement two methods getArticle and getPeople. In this part, JAPX played an important role. Because our JSON response has a JSON: API response format, we need to smooth and complex responses.
However, the above example works well; we need to make an explicit conversion:
json.decode
to get mapped json objectJapx.decode
to flatten the map.- Instantiate dart object with our model’s
fromJsonFactory
methods.
There are two problems with this approach:
- Explicit conversion will cause code duplication
- Service method Response<dynamic> return type.
Let's see how to deal with these problems...
7. Implement JsonConvertor for response type specification
In some way, we need to manipulate Chopper Responses to return the model type we defined earlier. Thanks to special interceptors called converters, we can handle the conversion of responses, requests, and errors. All we need to do is to create a converter and inject it into the Chopper client, which we use.
Let's create the jsonserializableeconverter class for Chopper Client. In order to do this, we need to extend our class from Chopper's JsonConverter class and override the convertResponse, convertRequest and convertError methods.
Now we convert in the convertResponse method, which also solves the code duplication problem, because this method is called every time a successful response is made. However, there is still a type conversion problem that needs to be resolved.
jsonRes.copyWith<ResultType>(body: JsonTypeParser.decode<Item>(flatJson["data"]))
This is the key statement to parse the response of the Dart model:
- In fact, we hope that the return type used by the service method ResultType is List or or BuiltList will be our return type. In order to define the return type in the service method, we need to add the model type we expect
After this change, whenever convertResponse is triggered, the ResultType will be People or Article.
- However, we still need to call the fromJsonFactory method of our model to convert the response object into a Dart object. In order to do this, we create the JsonTypeParser class, which will hold the conversion logic of the Dart object
JsonTypeParser has factories attribute of type Map<Type, JsonFactory>, which contains models and models from JsonFactory methods. Whenever we have a new model, we need to add its type and factory to the factory so that it can be parsed by the \_ decodeMap method. JsonSerializableConverter executes the decode <t> method, where t is ResultType or Item, and calls factory get of the matching type to instantiate our model.
Let us follow this change and modify the user interface part, we consume chopping service...
Let's insert jsonserializableeconverter into our chopper client:
According to these changes, we can now directly use the response body, which has type safety.
to sum up
I know that there are a lot of things to digest, but there are still a lot of things to discuss, such as JsonSerializable and Chopper's custom type converters that respond incorrectly. If I write a medium-level article, I will connect this topic.
All in all, what I want to show is that various response models can be solved by chopping and json serialization without losing the type-safe clean way.
© Cat brother
Past
Open source
GetX Quick Start
https://github.com/ducafecat/getx_quick_start
News client
https://github.com/ducafecat/flutter_learn_news
strapi manual translation
WeChat discussion group ducafecat
Series collection
Translation
https://ducafecat.tech/categories/%E8%AF%91%E6%96%87/
Open source project
https://ducafecat.tech/categories/%E5%BC%80%E6%BA%90/
Dart programming language basics
https://space.bilibili.com/404904528/channel/detail?cid=111585
Getting started with Flutter zero foundation
https://space.bilibili.com/404904528/channel/detail?cid=123470
Flutter actual combat from scratch news client
https://space.bilibili.com/404904528/channel/detail?cid=106755
Flutter component development
https://space.bilibili.com/404904528/channel/detail?cid=144262
Flutter Bloc
https://space.bilibili.com/404904528/channel/detail?cid=177519
Flutter Getx4
https://space.bilibili.com/404904528/channel/detail?cid=177514
Docker Yapi
https://space.bilibili.com/404904528/channel/detail?cid=130578
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。