Code Monkey home page Code Monkey logo

opencrud's Introduction

OpenCRUD

OpenCRUD is a GraphQL CRUD API specification for databases

Overview

OpenCRUD is a fully GraphQL compliant query language to access and modify data. OpenCRUD provides API flavours for many popular databases including MySQL and MongoDB.

For example, this OpenCRUD query retrieves a single user:

{
  user(where: { id: 4 }) {
    name
  }
}

returns:

{
  "user": {
    "name": "Mark Zuckerberg"
  }
}

Rationale

GraphQL is a flexible query language supporting many different data access patterns. In practice, simple CRUD operations turn out to be a very common pattern. Standardising this very common pattern enables the community to build tooling specific to the common CRUD style API.

Projects compatible with OpenCRUD

Feel free to create a PR to add your project to the list

Index

  • Specs
    • SDL for data modelling: non normative
    • relational
      • Intro
        • Areas covered
        • Focus on API, not implementation/runtime characteristics
      • Queries
        • Top level
          • Single fields multi fields
          • Multi field conenctions
          • Node field
        • Relations
          • Both simple and connection
          • Connections
            • Aggregations
            • Cursor
        • Filters
          • Data type specific filters
          • Single node
          • Multi node
          • Cross-relation filters
        • Aggregations
      • Mutations
      • Subscriptions
      • Generated type names

opencrud's People

Contributors

2color avatar aurelsicoko avatar dependabot[bot] avatar fluorescenthallucinogen avatar gromnan avatar kuldar avatar mlukaszczyk avatar schickling avatar sorenbs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opencrud's Issues

Pagination

skip/after/before/first/last don't seem to be documented anywhere?

Why not use required arrays with non-null items?

Why are the return type of a "get many entity query" [T]! and not [T!]!?
Is it expected that it can return null items? i.e: [T, null, T]

And for to-many relationships where the relationship is defined [T!]! why is the generated schema posts(...): [Post!] and not posts(...): [Post!]!? Is it here expected that it can return null instead of an empty array?

If it is not intentional it would be really helpful if the types could be changed. Its a bit frustrating that we have to check for null everywhere. If the return type was [T!]! it would clean up our code a lot.

Example:

Datamodel

type User {
  id: ID! @unique
  name: String!
  posts: [Post!]!
}

type Post {
  id: ID! @unique
  title: String!
}

Generated Schema

type User implements Node {
  id: ID!
  name: String!
  posts(
    where: PostWhereInput
    orderBy: PostOrderByInput
    skip: Int
    after: String
    before: String
    first: Int
    last: Int
  ): [Post!] # Why not [Post!]! here?
  postsConnection(
    where: PostWhereInput
    orderBy: PostOrderByInput
    skip: Int
    after: String
    before: String
    first: Int
    last: Int
  ): PostConnection!
}

type Post implements Node {
  id: ID!
  title: String!
}

type Query {
  users(
    where: UserWhereInput
    orderBy: UserOrderByInput
    skip: Int
    after: String
    before: String
    first: Int
    last: Int
  ): [User]! # Why not [User!]! here?
  user(where: UserWhereUniqueInput!): User
}

@relation

The document mentions an @relation directive but then never uses or explains it?

Full-text search

It would be useful to have a way to do full-text search without using external services such as Algolia. But we need a spec for that.

Plural query name

One of our users (see strapi/strapi#1198) faced an issue due to some English words which have particular plural forms. For example:

  • news/news
  • information/information
  • & more

How is the specification handling this case? Currently, I don't see anything which can manage it.

query {
  news(where: { id: "1" }) {
    name
  }
  news(where: { name_contains: "Karl" }) {
    name
  }
}

Should we put the prefix all before the plural name of the query?

query {
  news(where: { id: "1" }) {
    name
  }
  allNews(where: { name_contains: "Karl" }) {
    name
  }
}

Consider compositional WhereInput's for scalars.

I'm gonna preface this by saying I don't have high hopes for it being implemented, since it'd be, among other things, a breaking change.

Let's say I have a query like this

query getBooks {
  books {
    author {
      name
    }
    datePublished
    genre {
      name
    }
    title
  }
}

Things get a bit more verbose when you want to let the user apply some filters

query getBooks(
  $titleStartsWith: String
  $genres: [String!]
  $publishedAfter: DateTime
  $publishedBefore: DateTime
) {
  books(
    where: {
      title_starts_with: $titleStartsWith
      genre_in: $genres
      datePublished_gte: $publishedAfter
      datePublished_lt: $publishedBefore
    }
  ) {
    author {
      name
    }
    datePublished
    genre {
      name
    }
    title
  }
}

but it's still manageable. The problem is when more filtering comes into play (user wants to filter by title/author name starting with/ending with/equals). Each variable is its own thing, and each one gets hooked to a specific part of the where input, so the queries for dynamic front-end's can get pretty big.

query getBooks(
  $titleStartsWith: String
  $titleEndsWith: String
  $titleEquals: String
  $authorNameStartsWith: String
) # And so on.
{
  books(
    where: {
      title_starts_with: $titleStartsWith
      title_ends_with: $titleEndsWith
      title: $titleEquals
      author: { name_starts_with: $authorNameStartsWith }
      # And so forth.
    }
  ) {
    author {
      name
    }
    datePublished
    genre {
      name
    }
    title
  }
}

Things get worse when actually populating the variables. For example, if I had a filter option for each field

function getVariables(filters) {
  return {
    titleStartsWith: filters.title.startsWith,
    titleEndsWith: filters.title.endsWith,
    titleEquals: filters.title.equals,
    authorNameStartsWith: filter.authorName.startsWith,
  };
}

To make matters worse, this isn't reusable. It works for this table, but the same plumbing has to be redone if you want to apply this style to a table of magazine articles or blog posts. The interesting thing is that the part for filtering on the author can be made reusable, by passing an AuthorWhereInput as a variable

query getBooks($author) {
  books(where: {author: $author}) {
    name
  }
}

query getArticles($author) {
  articles(where: {author: $author}) {
    name
  }
}

So, for relational fields, filtering can be delegated from the query to the variables. The same query can be used (and persisted) to get information by any criteria of a relational field. So, I'm proposing something similar for the field itself.

query getBooks(
  $title: StringWhereInput
  $genre: GenreWhereInput
  $author: AuthorWhereInput
) {
  books(
    where: {
      title: $title
      genre: $genre
      author: $author
    }
  ) {
    author {
      name
    }
    datePublished
    genre {
      name
    }
    title
  }
}

404 to CRUD link

There is a broken link (the most interesting) in the index about CRUD mutations

OpenCRUD Roadmap?

This project has potential. However it hasn't been updated for 2 years now and I wonder what's the next development plan.

Especially that now Prisma v2 is already in beta, is OpenCRUD still used by the new Prisma.

I'd love us to have something "like OData but for GraphQL". I do like the way OpenCRUD reuses Relay Connections for the resultset format.

Other existing GraphQL CRUD-like specs:

Link to GitHub

Not sure if there's a link to this repo anywhere in the document?

GraphQL - error actualizar un campo

Hola,

Estoy intentando ejecutar un mutation que incremente en 1 un valor especifico de un campo pero el mutation no se ejecuta en el PlayGround me muestra error... cual puede ser el error ? la sintaxis que estoy usando no me salta ninguna observación.

Captura

Plural and convention for other language than english

As this git seems not active it is probably useless to leave an issue here. But, still, the openCRUD convention is supposed to be a working draft, so I am giving some work to think about.

Coming from strapi ( https://github.com/strapi/strapi/issues/8646 ), where similar issues have been pointed out. There is clearly a problem with the naming convention 2.4.1.6, especially for non-english languages.
English is a de facto standard in IT, ok, but why could we not name something in our databases using our own language? Let's say that non-developpers or non-english-speakers (they exist) would, for instance, use the strapi dashboard where everything is named according to the openCRUD convention and, thus, where everything is in english. It is a problem.

Deleting fields

I think we should cover how to specify that a field should be deleted. Personally I like the convention of setting the field to null:

mutation {
  updateUser(where: { id: "1" }, data: { name: "Karl", bio: null }) {
    id
  }
}

Directive handling

We should specify how directives are translated from the data model to the generated GraphQL API.

Naming Questions: Multi, Where, Data

OpenCRUD currently uses the word "multi" to designate queries that return multiple documents (as opposed to "single"). Currently, in Vulcan we use the word "list". I think "multi" is better actually, but before I make the switch I was just wondering if other alternatives had been explored? What kind of nomenclature do other data layers (dbs, etc.) use?

Also, what about "Where"? Coming from a Mongo background the word "Selector" seems more natural since "where" isn't really a noun ("what is this mutation's where?" sounds weird).

Finally, the mutation argument is named data. I wonder if that could be ambiguous in certain cases since that's also the name of Apollo Client's return value. What about document instead?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.