Metadata-Version: 2.1
Name: django-json-api
Version: 0.2.6
Summary: JSON API specification for Django services
Home-page: https://github.com/share-work/django-json-api
Author: Sharework
Author-email: root@sharework.co
Classifier: Programming Language :: Python :: 3.8
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: djangorestframework-jsonapi (==4.1.0)
Requires-Dist: djangorestframework (==3.12.2)
Requires-Dist: python-dateutil (==2.7.5)
Provides-Extra: all
Requires-Dist: black (==22.3.0) ; extra == 'all'
Requires-Dist: coverage (==5.4) ; extra == 'all'
Requires-Dist: django-coverage-plugin (==1.8.0) ; extra == 'all'
Requires-Dist: flake8 (==3.8.4) ; extra == 'all'
Requires-Dist: isort (==5.7.0) ; extra == 'all'
Requires-Dist: pre-commit (==2.10.0) ; extra == 'all'
Requires-Dist: pytest-cov (==2.11.1) ; extra == 'all'
Requires-Dist: pytest-django (==3.8.0) ; extra == 'all'
Requires-Dist: pytest (==6.2.2) ; extra == 'all'
Requires-Dist: requests-mock (==1.8.0) ; extra == 'all'
Requires-Dist: testfixtures (==6.17.1) ; extra == 'all'
Provides-Extra: dev
Requires-Dist: black (==22.3.0) ; extra == 'dev'
Requires-Dist: coverage (==5.4) ; extra == 'dev'
Requires-Dist: django-coverage-plugin (==1.8.0) ; extra == 'dev'
Requires-Dist: flake8 (==3.8.4) ; extra == 'dev'
Requires-Dist: isort (==5.7.0) ; extra == 'dev'
Requires-Dist: pre-commit (==2.10.0) ; extra == 'dev'
Requires-Dist: pytest-cov (==2.11.1) ; extra == 'dev'
Requires-Dist: pytest-django (==3.8.0) ; extra == 'dev'
Requires-Dist: pytest (==6.2.2) ; extra == 'dev'
Requires-Dist: requests-mock (==1.8.0) ; extra == 'dev'
Requires-Dist: testfixtures (==6.17.1) ; extra == 'dev'

# django-json-api

[![PyPI version](https://badge.fury.io/py/django-json-api.svg)](https://badge.fury.io/py/django-json-api)
[![codecov](https://codecov.io/gh/share-work/django-json-api/branch/develop/graph/badge.svg?token=hTGA39HrJV)](https://codecov.io/gh/share-work/django-json-api)
[![Reveal](https://circleci.com/gh/reveal-co/django-json-api.svg?style=shield&circle-token=727d6ee289cf310d7f2a473d02574506f6ea8ef7)](https://app.circleci.com/pipelines/github/reveal-co/django-json-api)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)


**django-json-api** uses Django's ORM interfaces as inspiration to serialize, request and
deserialize entities from databases of other microservices using (and benefiting from) the
[JSON:API](https://jsonapi.org/) specification.


## Installation

To install via pip:

```sh
pip install django-json-api
```

You can also install from the source:

```sh
git clone git@github.com:reveal-co/django-json-api.git
cd django-json-api
git checkout main
pip install -e .
```

## Getting started

Suppose you have a `django.db.models.Model` class inside microservice A, such as:

```python
from django.db import models

class Company(models.Model):
    name = models.CharField(max_length=256)
    domain = models.CharField(max_length=256)
    deleted_at = models.DateTimeField(null=True, default=None)
```

If you wish to consume it from microservice B, first add this inside the aforementioned model's
definition:


```python
    class JSONAPIMeta:
        resource_name = 'companies'
```

and define an instance of a `django_json_api.models.JSONAPIModel` inside microservice B:

```python
from django_json_api.models import JSONAPIModel
from django_json_api.fields import Attribute

class Company(JSONAPIModel):
    class Meta:
        api_url = MICROSERVICE_A_API_URL
        resource_type = 'companies'

    name = Attribute()
    domain = Attribute()
```

PS: `api_url` expects a url with protocol (i.e. starting with `http(s)://`) and ending with a trailing slash `/`.

Now, querying companies from microservice B is as easy as:

```python
  Company.objects.all()
  Company.objects.filter(name="Reveal")
  Company.objects.iterator()
  ...
```

You can also have entities in one microservice relate to entities in another by leveraging both `RelatedJSONAPIField`
and `WithJSONAPIQuerySet`. Take a look at this model definition from microservice B:

```python
from django.db import models
from django_json_api.django import RelatedJSONAPIField


class User(models.Model):
    name = models.CharField(max_length=256)
    company = RelatedJSONAPIField(json_api_model=Company)
    deleted_at = models.DateTimeField(null=True, default=None)
```

Here, `Company` is the `JSONAPIModel` defined above. This makes it possible, when querying for a user, to also
fetch its related company:

```python
user = User.objects.get(pk=1)
user.company # This will be resolved through an underlying HTTP request
```

In case of larger querysets, you might want to prefetch the relations as you do with django's `prefetch_related`. For
that, you imbue `User`'s manager using `WithJSONApiQuerySet`, which will grant the manager a new
method: `prefetch_jsonapi`.


## License

[MIT](LICENSE)
