Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pm-dev/kotlin-gremlin-ogm
An Object Graph Mapping Library for Kotlin and Gremlin
https://github.com/pm-dev/kotlin-gremlin-ogm
Last synced: 3 months ago
JSON representation
An Object Graph Mapping Library for Kotlin and Gremlin
- Host: GitHub
- URL: https://github.com/pm-dev/kotlin-gremlin-ogm
- Owner: pm-dev
- License: apache-2.0
- Created: 2018-04-10T18:30:14.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2019-01-28T03:45:45.000Z (almost 6 years ago)
- Last Synced: 2024-08-01T01:30:59.791Z (6 months ago)
- Language: Kotlin
- Size: 954 KB
- Stars: 32
- Watchers: 3
- Forks: 6
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-kotlin - Kotlin-Gremlin-OGM - A type-safe object/graph mapping framework for Gremlin enabled graph databases. (Libraries)
README
# The Object Graph Mapping Library for Kotlin and Gremlin
[![Build Status](https://travis-ci.org/pm-dev/kotlin-gremlin-ogm.svg?branch=master)](https://travis-ci.org/pm-dev/kotlin-gremlin-ogm)
[![Latest Release](https://img.shields.io/maven-metadata/v/http/central.maven.org/maven2/com/github/pm-dev/kotlin-gremlin-ogm/maven-metadata.xml.svg)](http://central.maven.org/maven2/com/github/pm-dev/kotlin-gremlin-ogm/)
[![Kotlin Version](https://img.shields.io/badge/kotlin-1.3.10-blue.svg)](http://kotlinlang.org/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)Gremlin is the graph traversal language for the Apache TinkerPop graph framework and is
supported by most graph database implementations.#### Basic Usage:
Define a Vertex
@Element("Person")
data class Person(
@ID
val id: Long? = null,
@Property("name")
val name: String)
Define a Relationshipval friends = ManyToManySymmetricEdgeSpec("friends")
val subordinates = SingleToManyEdgeSpec("boss_to_subordinates")
val boss = subordinates.inverse
Save a Vertexval mighael = graphMapper.saveV(Person(name = "Michael Scott"))
val dwight = graphMapper.saveV(Person(name = "Dwight Schrute"))
Save an EdgegraphMapper.saveE(friends from michael to dwight)
graphMapper.saveE(boss from michael to dwight)
Traverse an EdgegraphMapper.traverse(friends from michael) // returns List [ dwight ]
graphMapper.traverse(friends from dwight) // returns List [ michael ]
graphMapper.traverse(subordinates from michael) // returns List [ dwight ]
graphMapper.traverse(boss from dwight) // returns non-optional Person michealThe `graphMapper` is an implementation of the `GraphMapper` interface which requires two properties:
1. A `GraphTraversalSource` spawned from a tinkerpop graph
2. A `GraphDescription` which is easily instantiated using `CachedGraphDescription(vertices = setOf(Person::class))`#### Sample Starwars App
An interactive example can be run using the [starwars example project](https://github.com/pm-dev/kotlin-gremlin-ogm/tree/master/example).
From the repo root directory, run:./gradlew run
Then load GraphiQL at `http://localhost:5000/graphiql.html` to explore the data mapped with this library.
A small typescript + apollo + react web client that uses this starwars API can also be sampled:
cd example/frontend && yarn start
Then load `http://localhost:3000` (server must also be running)#### Installation:
- Gradle
compile 'com.github.pm-dev:kotlin-gremlin-ogm:0.21.0'- Maven
com.github.pm-dev
kotlin-gremlin-ogm
0.21.0
#### Library ExtensionsMix and match the following extensions to this library
- JanusGraph: [kotlin-janusgraph-ogm](https://github.com/pm-dev/kotlin-gremlin-ogm/tree/master/kotlin-janusgraph-ogm)
- GraphQL: [kotlin-gremlin-graphql](https://github.com/pm-dev/kotlin-gremlin-ogm/tree/master/kotlin-gremlin-graphql)
- ReactiveX: [kotlin-rx-ogm](https://github.com/pm-dev/kotlin-gremlin-ogm/tree/master/kotlin-rx-ogm)#### Features:
- Take full advantage of Kotlin's type-safety. Traversals return either a list, non-optional, or optional based on
whether a relationship is defined as to-many, to-single, or to-optional, respectively.
- Map and filter traversals using your Kotlin objects.
- No runtime code generation. Other ogms use third-party libraries that generate new classes at runtime.
- External dependencies are limited to: Kotlin's standard library, the gremlin-driver, and slf4j.
- Annotation-based so you can bring your current POJO domain objects.
- Kotlin compiler plugins 'all-open' and 'no-arg' are not required.#### Why use a graph database and ogm?
- Graph databases are powerful for modeling data that is highly connected.
- This OGM enables for strong typing of domain objects in the application layer while removing the need for a schema enforced by the db.
- This allows for data to be backed by a NoSQL datastore. NoSQL datastores are horizontally scalable and can be partition tolerant.
- This makes migrations much easier.#### Limitations:
- This library will not work if you're trying to connect to a Gremlin Server remotely. This library creates traversals
that call back into the library, thus, your graph implementation must be running within the same JVM.
- For this reason, connecting to Amazon Neptune is not currently supported, as Amazon Neptune does not support
calling arbitrary java from within a traversal.#### Design Principles:
- Common use-cases should be easy. Uncommon use-cases should be possible.
- Performance is important.
- Fail fast with helpful exceptions.#### Native property types are stored directly in the graph as property values:
- `Boolean`
- `Byte`
- `Double`
- `Float`
- `Int`
- `Long`
- `String`If your Gremlin implementation does not support one of these native types, make sure to register a
property mapper for they type with your `GraphDescription`
or declare a [`@Mapper`](https://github.com/pm-dev/kotlin-gremlin-ogm/blob/master/kotlin-gremlin-ogm/src/main/kotlin/org/apache/tinkerpop/gremlin/ogm/annotations/Mapper.kt) for that property.#### Built-in property mappers:
- [`Instant` -> `String`](https://github.com/pm-dev/kotlin-gremlin-ogm/blob/master/kotlin-gremlin-ogm/src/main/kotlin/org/apache/tinkerpop/gremlin/ogm/mappers/scalar/InstantPropertyMapper.kt)
- [`UUID` -> `String`](https://github.com/pm-dev/kotlin-gremlin-ogm/blob/master/kotlin-gremlin-ogm/src/main/kotlin/org/apache/tinkerpop/gremlin/ogm/mappers/scalar/UUIDPropertyMapper.kt)
- [`URL` -> `String`](https://github.com/pm-dev/kotlin-gremlin-ogm/blob/master/kotlin-gremlin-ogm/src/main/kotlin/org/apache/tinkerpop/gremlin/ogm/mappers/scalar/URLPropertyMapper.kt)
- [`BigDecimal` -> `String`](https://github.com/pm-dev/kotlin-gremlin-ogm/blob/master/kotlin-gremlin-ogm/src/main/kotlin/org/apache/tinkerpop/gremlin/ogm/mappers/scalar/BigDecimalPropertyMapper.kt)To use other property types, register your custom property mapper with `GraphDescription` by returning a `PropertyMapper` from the `getScalarPropertyMapper` function
a [`@Mapper`](https://github.com/pm-dev/kotlin-gremlin-ogm/blob/master/kotlin-gremlin-ogm/src/main/kotlin/org/apache/tinkerpop/gremlin/ogm/annotations/Mapper.kt) for that property.#### How the mapping works:
- A description of your graph, based annotations, is processed and cached when your `GraphMapper` is instantiated.
- Using this description of the graph, we can create 'vertex mappers' that know how to serialize/deserialize objects marked with `@Element` to/from
the graph.
- Nested objects are not natively supported by Gremlin. When mapping a nested object to properties of a vertex,
the property key uses periods ('.') to denote a nested object. For example:Given:
class Name(val first: String, val last: String)
class Person(val name: Name)...is serialized in the graph using vertex properties:
"name.first" -> "Lionel"
"name.last" -> "Messi"- `List` and `Set` types are supported. These collections are stored as follows:
Given:
class Name(val first: String, val last: String)
class Person(val names: Set)
...is serialized in the graph using vertex properties:"names.0.first" -> "Cassius"
"names.0.last" -> "Clay"
"names.1.first" -> "Muhammad"
"names.1.last" -> "Ali"To preserve the difference between a null and empty collection or map, we use
a special `UUID` token. For example if the names `Set` was empty:"names" -> "474A56F1-6309-41B5-A632-AD53F57DBDAE"
...or in the case of an empty map, the special `UUID` is: `9B94DCB9-D405-47C1-B56D-72F83C4E81D3`.
#### Legal:
Licensed under the Apache Software License 2.0.
This code is in no way affiliated with, authorized, maintained, sponsored or endorsed by the Apache Software Foundation.