![Neuron Logo](https://github.com/neuronlabs/neuron-core/raw/HEAD/logo_teal.svg)
Neuron
![GitHub](https://img.shields.io/github/license/neuronlabs/neuron)
Neuron is the golang framework that uses both code generation and interfaces to create services and microservices.
What is Neuron?
Neuron is a Golang framework that enables creation of performance critical, easily scalable services with a focus on the models - not the infrastructure.
It defines a set of structures, interfaces and functions that handles model ORM-like database access, an API server with
access to its resources, authorization and authentication basics, encoding based marshaling as well as multi version access.
Design
The Aim of this project was to provide a fast way of creating performance critical services.
Model mapping
With this assumption it was necessary to define interfaces for the models and its database access, a server that
handles external request and encodes using defined codecs.
In order to achieve it each model would become scanned and mapped twice - using compile-time code scan and generation and then runtime - dynamic mapping
.
This allows getting rid of unnecessary reflection with an ability to know the model on runtime.
Controller
Each model used by the Neuron service is stored within the controller
and mapped to it's related repository
.
Repository and Queries
A repository
is a database access interface that allows to execute the queries within specific data storage.
The service uses query
scopes which defines all required information about the resource request.
Database
In order to create and execute queries a package database
provide set of functions, structures and interfaces that handles
provided query.Scope
reduce it to the simplest possible form and execute in related model's repository.
This package provides a way to query multiple disjoint repositories and merge its results concurrently using simple query builders.
Transactions
This approach required to implement more complicated transaction system.
Each model may use a different repository, thus an execution of the transaction needs to be divided for each repository.
Each repository is also responsible only for its part of the transaction.
The whole process of the transaction is being orchestrated by the database.Tx
.
Install
go get github.com/neuronlabs/neuron
Related packages
Neuron requires the model to implement multiple interfaces. In order to make this process faster and easier a code generation
tool neurogonesis
- https://github.com/neuronlabs/neuron-extensions/tree/master/neurogonesis is implemented.
It contains a CLI tool that might be used as go:generate
to scan golang code and implement all required interfaces for your models.
See to check more details about go:generate
- https://blog.golang.org/generate.
It could also generate Collections
- which are the model specific non-interface database query builder and composer.
Packages in the Neuron
repository provides mostly basic structures, interfaces and functions, in order not to limit it to specific
implementations.
Repository https://github.com/neuronlabs/neuron-extensions -
contains implementations for specific codecs, servers, repositories and authorization/authentication services.
All of these could be used as modules that creates your neuron service faster and better.
How to get known with the Neuron better? Visit repository https://github.com/neuronlabs/neuron-examples - that shows examples on how the services could be created,
for specific usages.
Quick Start
Define the models
models.go
package main
type User struct {
ID int
Name string
Surname string
Pets []*Pet `neuron:"foreign=OwnerID"`
}
type Pet struct {
ID int
Name string
Owner *User
OwnerID int
}
Create repository and server
repository.go
package main
import (
"os"
"github.com/neuronlabs/neuron-extensions/repository/postgres"
"github.com/neuronlabs/neuron/log"
"github.com/neuronlabs/neuron/repository"
)
const (
envDefaultPostgres = "NEURON_DEFAULT_POSTGRES"
envPetsPostgres = "NEURON_PETS_POSTGRES"
)
func defaultRepository() *postgres.Postgres {
uriCredentials, ok := os.LookupEnv(envDefaultPostgres)
if !ok {
log.Fatalf("required environment variable: %s not found", envDefaultPostgres)
}
return postgres.New(repository.WithURI(uriCredentials))
}
func petsRepository() *postgres.Postgres {
uriCredentials, ok := os.LookupEnv(envPetsPostgres)
if !ok {
log.Fatalf("required environment variable %s not found", envPetsPostgres)
}
return postgres.New(repository.WithURI(uriCredentials))
}
Server
package main
import (
"github.com/neuronlabs/neuron-extensions/server/http"
"github.com/neuronlabs/neuron-extensions/server/http/api/jsonapi"
"github.com/neuronlabs/neuron-extensions/server/http/middleware"
)
func getJsonAPI() *jsonapi.API {
api := jsonapi.New(
jsonapi.WithMiddlewares(middleware.ResponseWriter(-1), middleware.LogRequest),
jsonapi.WithPathPrefix("/v1/api"),
jsonapi.WithStrictUnmarshal(),
jsonapi.WithDefaultHandlerModels(&User{}, &Pet{}),
)
return api
}
func getServer() *http.Server {
jsonAPI := getJsonAPI()
s := http.New(
http.WithAPI(jsonAPI),
http.WithPort(8080),
)
return s
}
Main service
main.go
package main
import (
"context"
"net/http"
"github.com/neuronlabs/neuron"
"github.com/neuronlabs/neuron/log"
serverLogs "github.com/neuronlabs/neuron-extensions/server/http/log"
)
func main() {
log.NewDefault()
n := neuron.New(
neuron.Server(getServer()),
neuron.DefaultRepository(defaultRepository()),
neuron.RepositoryModels(petsRepository(), &Pet{}),
neuron.Models(Neuron_Models...),
neuron.MigrateModels(Neuron_Models...),
neuron.Collections(Neuron_Collections...),
)
log.SetLevel(log.LevelDebug3)
serverLogs.SetLevel(log.LevelDebug3)
ctx := context.Background()
if err := n.Initialize(ctx); err != nil {
log.Fatalf("Initialize failed: %v", err)
}
for _, endpoint := range n.Server.GetEndpoints() {
log.Infof("Endpoint [%s] %s", endpoint.HTTPMethod, endpoint.Path)
}
if err := n.Run(ctx); err != nil && err != http.ErrServerClosed {
log.Errorf("Running neuron service failed: %s", err)
}
}
Packages
The neuron
is composed of the following packages:
auth
- defines basic interfaces and structures used for neuron authentication and authorization.codec
- is a set structures and interfaces used on marshal process.core
- defines a structure that keeps and maps all models to related repositories.database
- defines interfaces, functions and structures that allows execution of queries.errors
- neuron defined errors.log
- is the neuron service logging interface structure for the neuron based applications.filestore
- defines a common interface for the file stores.mapping
- contains the information about the mapped models their fields and settings.query
- contains structures used to create queries, sort, pagination on base of mapped models.query/filters
- contains query filters structures and implementations.repository
- is a package used to store and register the repositories.server
- defines interfaces used as the servers.service
- contains core neuron service definitions.store
- key-value stores structures and implementations.
Docs