Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 54 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ query getProducts {
}
```

**Note**: The corresponding SQL for creating the table (POSTGRES)

```sql
CREATE TABLE products (
id SERIAL NOT NULL,
name TEXT NOT NULL,
price INTEGER NOT NULL,
owner_id INTEGER NOT NULL,
category_id INTEGER NOT NULL,
PRIMARY KEY(id)
);
```

## Secure out of the box

In production all queries are always read from locally saved copies not from what the client sends hence clients cannot modify the query. This makes
Expand Down Expand Up @@ -143,44 +156,52 @@ go get github.com/dosco/graphjin/core/v3
package main

import (
"context"
"database/sql"
"fmt"
"log"

"github.com/dosco/graphjin/core/v3"
_ "github.com/jackc/pgx/v4/stdlib"
"context"
"database/sql"
"log"
"net/http"

"github.com/dosco/graphjin/core"
"github.com/go-chi/chi/v5"
_ "github.com/jackc/pgx/v5/stdlib"
)

func main() {
db, err := sql.Open("pgx", "postgres://postgres:@localhost:5432/example_db")
if err != nil {
log.Fatal(err)
}

gj, err := core.NewGraphJin(nil, db)
if err != nil {
log.Fatal(err)
}

query := `
query {
posts {
id
title
}
}`

ctx := context.Background()
ctx = context.WithValue(ctx, core.UserIDKey, 1)

res, err := gj.GraphQL(ctx, query, nil, nil)
if err != nil {
log.Fatal(err)
}
db, err := sql.Open("pgx", "postgres://postgres:@localhost:5432/exampledb?sslmode=disable")
if err != nil {
log.Fatal(err)
}

gj, err := core.NewGraphJin(nil, db)
if err != nil {
log.Fatal(err)
}

query := `
query getPosts {
posts {
id
title
}
posts_cursor
}`

router := chi.NewRouter()
router.Get("/", func(w http.ResponseWriter, request *http.Request) {
context := context.WithValue(request.Context(), core.UserIDKey, 1)
res, err := gj.GraphQL(context, query, nil, nil)
if err != nil {
log.Fatal(err)
return
}
w.Write(res.Data)
})

log.Println("Go server started on port 3000")
http.ListenAndServe(":3000", router)

fmt.Println(string(res.Data))
}

```

### Use GraphJin Service
Expand Down
4 changes: 4 additions & 0 deletions core/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ func (rc *ReqConfig) SetNamespace(ns string) {
rc.ns = &ns
}

// GetNamespace is used to get the namespace requests within a single instance of GraphJin
func (rc *ReqConfig) GetNamespace() (string, bool) {
if rc.ns != nil {
return *rc.ns, true
Expand Down Expand Up @@ -445,6 +446,7 @@ func (gj *graphjin) newGraphqlReq(rc *ReqConfig,
return
}

// Set is used to set the namespace, operation type, name and query for the GraphQL request
func (r *graphqlReq) Set(item allow.Item) {
r.ns = item.Namespace
r.op = qcode.GetQTypeByName(item.Operation)
Expand All @@ -453,11 +455,13 @@ func (r *graphqlReq) Set(item allow.Item) {
r.aschema = item.ActionJSON
}

// GraphQL function is our main function it takes a GraphQL query compiles it
func (gj *graphjin) queryWithResult(c context.Context, r graphqlReq) (res *Result, err error) {
resp, err := gj.query(c, r)
return &resp.res, err
}

// GraphQL function is our main function it takes a GraphQL query compiles it
func (gj *graphjin) query(c context.Context, r graphqlReq) (
resp graphqlResp, err error,
) {
Expand Down
14 changes: 14 additions & 0 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (gj *graphjin) getIntroResult() (data json.RawMessage, err error) {
return
}

// Initializes the database discovery process on graphjin
func (gj *graphjin) initDiscover() (err error) {
switch gj.conf.DBType {
case "":
Expand All @@ -84,6 +85,7 @@ func (gj *graphjin) initDiscover() (err error) {
return
}

// Private method that does the actual database discovery for initDiscover
func (gj *graphjin) _initDiscover() (err error) {
if gj.prod && gj.conf.EnableSchema {
b, err := gj.fs.Get("db.graphql")
Expand Down Expand Up @@ -129,6 +131,7 @@ func (gj *graphjin) _initDiscover() (err error) {
return
}

// Initializes the database schema on graphjin
func (gj *graphjin) initSchema() error {
if err := gj._initSchema(); err != nil {
return fmt.Errorf("%s: %w", gj.dbtype, err)
Expand Down Expand Up @@ -186,6 +189,7 @@ func (gj *graphjin) _initSchema() (err error) {
return
}

// Initializes the qcode compilers
func (gj *graphjin) initCompilers() (err error) {
qcc := qcode.Config{
TConfig: gj.tmap,
Expand Down Expand Up @@ -273,6 +277,7 @@ func (gj *graphjin) executeRoleQuery(c context.Context,
return
}

// Returns the operation type for the query result
func (r *Result) Operation() OpType {
switch r.op {
case qcode.QTQuery:
Expand All @@ -286,26 +291,32 @@ func (r *Result) Operation() OpType {
}
}

// Returns the namespace for the query result
func (r *Result) Namespace() string {
return r.ns
}

// Returns the operation name for the query result
func (r *Result) OperationName() string {
return r.op.String()
}

// Returns the query name for the query result
func (r *Result) QueryName() string {
return r.name
}

// Returns the role used to execute the query
func (r *Result) Role() string {
return r.role
}

// Returns the SQL query string for the query result
func (r *Result) SQL() string {
return r.sql
}

// Returns the cache control header value for the query result
func (r *Result) CacheControl() string {
return r.cacheControl
}
Expand Down Expand Up @@ -370,6 +381,7 @@ func (s *gstate) debugLogStmt() {
}
}

// Saved the query qcode to the allow list
func (gj *graphjin) saveToAllowList(qc *qcode.QCode, ns string) (err error) {
if gj.conf.DisableAllowList {
return nil
Expand Down Expand Up @@ -399,10 +411,12 @@ func (gj *graphjin) saveToAllowList(qc *qcode.QCode, ns string) (err error) {
return gj.allowList.Set(item)
}

// Starts tracing with the given name
func (gj *graphjin) spanStart(c context.Context, name string) (context.Context, Spaner) {
return gj.trace.Start(c, name)
}

// Retry operation with jittered backoff at 50, 100, 200 ms
func retryOperation(c context.Context, fn func() error) (err error) {
jitter := []int{50, 100, 200}
for i := 0; i < 3; i++ {
Expand Down
1 change: 1 addition & 0 deletions core/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/dosco/graphjin/core/v3/internal/sdata"
)

// Initializes the graphjin instance with the config
func (gj *graphjin) initConfig() error {
c := gj.conf

Expand Down
Loading